SpringMVC 应知应会
springMVC 是表现层技术,可以用来代替 struts2,下面是简略图:主要是处理器和视图,只有这两个部分需要编写代码。
springMVC 三大组件:处理器映射器,处理器适配器,视图解析器。
下面是 SpringMVC的细节图:
整个流程:
- 客户端的请求到达前端控制器 DispatcherServlet
- DispatcherServlet 收到请求后调用 HandlerMapping 处理器映射器
- 处理器映射器根据请求的 url 找到具体的处理器,生成处理器对象以及处理器拦截器【不一定有,但是有的话一定会生成】,并将生成的对象交给 DispatcherServlet
- DispatcherServlet 接收到处理器映射器反馈的信息,通过 HandlerAdapter 处理器适配器找到对应的处理器
- 执行处理器的逻辑【处理器也叫后端控制器,Controller 】
- Controller 执行完毕后返回 ModelAndView 对象【也可以返回 String】
- 再次回到 HandlerAdapter,HandlerAdapter 将 Controller 的执行结果 ModelAndView 返回給 DispatcherServlet,
- DispatcherServlet 接收到 ModelAndView 之后,调用 ViewReslover 视图解析器
- ViewReslover 解析猴年返回具体的 View 对象
- DispatcherServlet 对返回回来的 View 对象进行渲染【即将模型数据填充至视图】
- DispatcherServlet 响应客户端的请求
上述的十一个步骤,其中需要编写代码的只有处理器【Handler 即 Controller】和 视图【View】,其他的只需要配置即可。
处理器的编写:
1 . 处理器类需要添加配置成 bean,因为是在表现层,所有使用的是 @Controller注解,
2 . 处理器中的方法需要使用 @RequestMapping(“url”)注解
3 . 处理器中方法的形参列表支持的几个特殊的对象:HttpServletRequest,HttpServletResponse,HttpServletSession,
见名知意,前端控制器会自动将这三个对象进行封装,便于方法内部获取请求参数和设置参数。
4 . 参数列表还支持一个参数——Modle【这个类是个接口,其子类 ModelMap】 ,但是它不是用来获取请求参数,
而是通过它向 request域存储数据,向视图传递数据【视图可以理解为 jsp,但视图不只是 jsp】,
5 . 处理器类中方法支持的返回值类型有:
- ModelAndView —— 携带了数据和要响应的视图【数据存储在 request域中】
- String —— 携带了响应的视图,一般结合 Model形参使用,一个携带响应的视图,一个携带数据【数据存储在 request域中】
- void —— 一般用于处理 AJAX 的请求,返回的数据由 Model形参来携带数据【或者其子类 ModelMap】,然后使用 request的转发或者 response进行重定向
小小总结:使用 ModelAndView,Model,ModelMap携带数据都是存储在了 request域中了,【 此时请求还未结束,也就是request对象还存活着 】,在 jsp页面使用 JSTL即可获取数据。
例子:
@Controller
public class ItemController { @Autowired
private ItemService itemService; /**
* 显示商品列表
*
* @return
*/
@RequestMapping("/itemEdit")
public String queryItemById(HttpServletRequest request, ModelMap model) {
// 从request中获取请求参数
String strId = request.getParameter("id");
Integer id = Integer.valueOf(strId); // 根据id查询商品数据
Item item = this.itemService.queryItemById(id); // 第一种方式:使用 ModelAndView ----------------------------
// 把结果传递给页面
// ModelAndView modelAndView = new ModelAndView();
// 把商品数据放在模型中
// modelAndView.addObject("item", item);
// 设置逻辑视图
// modelAndView.setViewName("itemEdit");
// 返回携带数据和视图的 ModelAndView对象
// return modelAndView;
// 第二种方式:使用 Model --------------------------------------
// 把商品数据放在模型中,其实是放在了 request域中
model.addAttribute("item", item);
// 返回视图的名字,也就是 jsp的名字【jsp视图的路径前缀和后缀需在 springmvc.xml中配置】
return "itemEdit";
}
}
上面代码中写到的视图路径前缀和后缀的配置如下:【也就是配置视图解析器】
<!-- 配置视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置逻辑视图的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置逻辑视图的后缀 -->
<property name="suffix" value=".jsp" />
</bean>
需要的配置:
1 . 添加 springmvc.xml文件,配置包扫描器,用于扫描 Controller
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置controller扫描包,多个包之间用,分隔 -->
<context:component-scan base-package="com.msym.springmvc.controller" /> </beans>2 . 配置前端控制器,在 web.xml 中配置 DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>springmvc-first</display-name>
<!-- 配置 SpringMVC 前端控制器 -->
<servlet>
<servlet-name>springmvc-first</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定 SpringMVC 配置文件 -->
<!-- SpringMVC 的配置文件的默认路径是 /WEB-INF/${servlet-name}-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet> <servlet-mapping>
<servlet-name>springmvc-first</servlet-name>
<!-- 设置所有以 action结尾的请求进入 SpringMVC -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>3 . 创建 Controller ,Controller只是一个普通 Java 类,需要使用 @Controller 进行注解,其中的方法使用 @RequestMapping 进行注解
4 . 在 springmvc.xml 中配置处理器映射器,处理器适配器,视图解析器【下面的第五步可以替代这一步】
<!-- 配置处理器映射器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<!-- 配置处理器适配器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />5 . 可以采用注解驱动的方式,代替了处理器映射器,处理器适配器的配置。【第五步可以完全替代第四步】
<!-- 注解驱动 -->
<mvc:annotation-driven />
SpringMVC 的拦截器:
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
之所以有预处理和后处理,是因为拦截器在处理器前后都会执行,只不过执行的方法不一样。
自定义拦截器需要实现 HandlerIntercept 接口,下面是【爱上笔记】中的一个拦截器类:
package cn.evelynn.cloudnote.interceptors; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.fasterxml.jackson.databind.ObjectMapper; import cn.evelynn.cloudnote.entity.User;
import cn.evelynn.cloudnote.util.JsonResult; /**
* 拦截器:用于拦截未登录的用户
* @author 码上猿梦
* http://www.cnblogs.com/daimajun/
*/
@Component
public class AccessInterceptor implements HandlerInterceptor { /**
* 用于判断用户是否登录,
* 未登录则拦截,
* 已登录就放行
*/
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception {
HttpSession session = req.getSession();
//判断用户是否登录
User user = (User) session.getAttribute("user");
if (user == null) {
// 利用response对象返回结果,告诉浏览器是Json格式,编码为UTF-8
res.setContentType("application/json;charset=UTF-8");
PrintWriter out = res.getWriter();
//ObjectMapper能将java对象转换为匹配Json的结构
ObjectMapper om = new ObjectMapper();
//将字符串转换为Json格式的字符串
String json = om.writeValueAsString(new JsonResult("请重新登录!"));
out.write(json);
//刷新缓冲区,向浏览器写出数据
res.flushBuffer();
return false;
}
//放行
return true;
} // controller执行后但未返回视图前调用此方法
// 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub } // controller执行后且视图返回后调用此方法
// 这里可得到执行controller时的异常信息
// 这里可记录操作日志
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub }
}
然后就是配置拦截器了,需要在 springmvc.xml 文件中配置拦截器:
<!-- 配置Interceptor -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 请求 /note/ 和 /notebook/ 资源的请求都进入拦截器 -->
<mvc:mapping path="/note/*" />
<mvc:mapping path="/notebook/*" />
<!-- AccessInterceptor 类采用了注解注册bean -->
<ref bean="accessInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
自定义异常类:
SpringMVC 应知应会的更多相关文章
- 测试TwemProxy的应知应会
一.背景 最近中间件开发组对twemproxy的发现注册机制做了改造,之前没有接触过twemproxy,借这次测试的机会,初步学习了一下twemproxy相关的知识:下面用"测试语言&quo ...
- Markdown的应知应会
Markdown介绍 什么是Markdown Markdown是一种纯文本.轻量级的标记语言,常用作文本编辑器使用.和记事本.notepad++相比,Markdown可以进行排版:和Word相比,Ma ...
- Linux用户应知应会的7个‘ls’命令的独特技巧
在前面我们系列报道的两篇文章中,我们已经涵盖了关于‘ls’命令的绝大多数内容.本文时‘ls命令’系列的最后一部分.如果你还没有读过该系列的其它两篇文章,你可以访问下面的链接. Linux中的15个基本 ...
- 【应知应会】15个常用的JavaScript字符串操作方法
1 初始化 //常用初始化方法 var stringVal = "hello iFat3"; //构造函数创建方法 var stringObj = new String(" ...
- Hibernate 应知应会
Hibernate 的关联关系的配置: 一对一外键约束: 举例子是一个丈夫和妻子:[一个丈夫只能有一位妻子] 表结构: CREATE TABLE `tbl_hus` ( `uuid` ) NOT NU ...
- Struts2 应知应会
struts.xml 文件的 action 的配置: Struts2 中结果类型的配置来自于下面: 其中: dispatcher:转发技术,转发到一个 jsp 视图 redirect:重定向到一个 j ...
- .NET架构开发应知应会
.NET程序是基于.NET framework..NET Core.Mono.UWP[.NET实现]开发和运行的 ,定义以上[.NET实现]的标准规范称为.NET Standard L1:.NET S ...
- Java 多线程应知应会
请简单说说 synchronized 关键字的底层原理 java 说到多线程绝对绕不开 synchronized,很多 java 工程师对 synchronized 是又爱又恨.为什么呢?主要原因包括 ...
- 关于HDFS应知应会的N个问题 | 技术点
1. Namenode的安全模式 ? 安全模式是Namenode的一种状态(Namenode主要有active/standby/safemode三种模式). 2. 哪些情况下,Namenode会进入安 ...
随机推荐
- 20155226-虚拟机与Linux之初体验
虚拟机与Linux之初体验 虚拟机的安装 虚拟机对我来说不是很了解,但今天在安装过程中加深了我的理解.虚拟机是一个在原来系统基础上进行的又一个系统安装,可以在不影响前者的情况下完成一些其不能解决的问题 ...
- 20155315 2016-2017-2 《Java程序设计》第一周学习总结
教材学习内容总结 第一章中提到了Java的前世今生和三大平台,我了解到Java SE包括JVM,JRE,JDK和Java语言.java最基本的特性之一是"跨平台",这使得Java语 ...
- WPF中。。DataGrid 实现时间控件和下拉框控件
DatePicker 和新的 DataGrid 行 用户与 DataGrid 中日期列的交互给我造成了很大的麻烦. 我通过将一个 Data Source 对象拖动到 WPF 窗口上,创建了一个 Dat ...
- 【BZOJ4362】isn
[BZOJ4362]isn 题面 bzoj 题解 设\(f[i][j]\)表示当前在\(i\),长度为\(j\)的最长不降子序列有多少个 这个可以用树状数组\(n^2logn\)求出 设\(g[i]\ ...
- 记录使用jQuery和Python抓取采集数据的一个实例
从现成的网站上抓取汽车品牌,型号,车系的数据库记录. 先看成果,大概4w条车款记录 一共建了四张表,分别存储品牌,车系,车型和车款 大概过程: 使用jQuery获取页面中呈现的大批内容 能通过页面一次 ...
- 每日 mark
SIGNAL=${SIGNAL:-TERM} PIDS=$(jps -lm | grep -i 'kafka\.Kafka' | awk '{print $1}')if [ -z "$PID ...
- mfs分布式系统从理论简介到实战部署
文章前面想说的话:这篇博客写出来真是有点累到了,本来昨天就基本就写好了,放在草稿里面,今天打开就没有了!!唉,就尼玛离我而去了,只有重写,然后中间虚拟机还“爆炸”重启又搞了一会,不容易呀!!希望各位博 ...
- 英特尔® 实感™ 摄像头 (F200) 应用如何实现最佳用户体验
英特尔开发人员专区原文 由于视频不能直接嵌入, 请点击视频标题观看.谢谢. 英特尔® 实感™ 技术支持我们重新定义如何与计算设备交互,包括允许用户通过手势自然交互. 为了帮助大家了解使用英特尔® 实感 ...
- 美国末日AI System设计分享
引言 好久没有写博客了,这半年在游戏公司工作,过得比较充实,每天不是add feature就是debug,所以忽视了写博客.今天发一篇关于AI博客. 主要是最近看了一些关于"The Last ...
- 列出连通集(mooc)
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1 ...

