SpringMVC学习

SpringMVC

ssm:mybatis+spring+springMVC
什么是mvc?

  • mvc是模型(Model),视图,控制器,的简写,是一种软件设计规范
  • 是将业务逻辑,数据,显示分离的方法来组织代码
  • MVC主要作用是降低了视图与业务逻辑间的双向偶合。
  • MVC不是一种设计模式,MVC是一种架构模式,当然不同的MVC存在差异

运行流程
SpringMVC学习

  1. 用 户 向 服 务 器 发 送 请 求 , 请 求 被 Spring 前 端 控 制 Servelt
    DispatcherServlet 捕获;

2.前端控制器DispatcherServlet接收请求后,调用处理器映射
HandlerMapping。
处理器映射器 HandlerMapping 根据请求的 url 找到处理该请求的处理器
Handler ( 即 Controller ) , 将 处 理 器 Handler 返 回 给 前 端 控 制 器
DispatcherServlet。

  1. DispatcherServlet 根 据 获 得 的 Handler , 选 择 一 个 合 适 的
    HandlerAdapter。 在填充 Handler 的入参过程中,根据你的配置,Spring 将
    帮你做一些额外的工作:
    HttpMessageConveter: 将请求消息(如 Json、xml 等数据)转换成一
    个对象,将对象转换为指定的响应信息
    数据转换:对请求消息进行数据转换。如 String 转换成 Integer、Double

    数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字
    或格式化日期等
    数据验证: 验证数据的有效性(长度、格式等),验证结果存储到
    BindingResult 或 Error 中

  2. Handler(自己的控制器)执行完成后,向 DispatcherServlet 返回一个
    ModelAndView 对象;

  3. 根据返回的 ModelAndView,选择一个适合的 ViewResolver(必须是已经
    注册到 Spring 容器中的 ViewResolver)返回给 DispatcherServlet ;

  4. ViewResolver 结合 Model 和 View,来渲染视图

  5. 将渲染结果返回给客户端。

搭建SpringMVC
jar包

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>

配置 DispatcherServlet
在 web.xml 文件中配置 DispatcherServlet
配置 spring 核心请求分发器

<servlet>
<servlet-name>application</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 找 web-inf/classes/配置文件 -->
<param-value>classpath:application.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- 请求映射 -->
<servlet-mapping>
<servlet-name>application</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

我们会发现 DispatcherServlet 从 HttpServlet 继承而来。所以它是一个标准的
Servlet,我们上一章在 web.xml 中配置了它,而且知道它启动的时候会加载
Spring 配置文件.

开启 SpringMVC 注解
开启spring注解

<mvc:annotation-driven></mvc:annotation-driven>

控制器类搭建
@Controller 用于标记在一个类上,使用它标记的类就是一个 SpringMVC
Controller 对象. Spring 配置中指定了自动扫描的 basepackage 后,Spring 会扫描这些包以及
子包中的使用了@Controller 标识的类,然后将类加入到 Spring IOC 容器中,
注入依赖。 @RequestMapping 注解是一个用来处理请求地址映射的注解,可用于类或方
法上。
接收请求
@RequestMapping
它的作用就是与请求相匹配,如果匹配上了,所修饰的方法才会被执行。这里我
们只需要关注两个属性:
value :请求的路径,这个路径相对于应用的上下文,它是 path 的别名。类型是
一个 String[] ,也就是说它可以匹配多个请求路径
method: 请求的方法。我们知道 HTTP 协议的请求方式有 GET 和 POST. 或者使用@GetMapping, @PostMapping
当前的请求只有与@RequestMapping 上指定的属性都匹配的时候,才会执行
它 标 注 的 方 法 。 下 面 分 析 几 个 例 子 , 假 设 应 用 的 上 下 文 路 径 为
“http://localhost:9090/”
@RequestMapping("/users")请求的路径为 “http://localhost:9090/users” , 请求方式没有限制,即可以是 GET 也可以是 POST,还能是其它的几个
@RequestMapping(value="/users", method= RequestMethod.GET) 请求
路径为"http://localhost:9090/users", 请求方式只能是 GET。 @RequestMapping(value="/users", method={ RequestMethod.GET , RequestMethod.POST}) 请求路径为“http://localhost:9090/users”, 请求
方式只能是 GET 或者 POST。
获取请求数据
我们编写处理器方法的目的,就是为了处理客户端提交的数据,而客户端的提交
是按照 HTTP 协议报文格式来提交的,下面我们分析一段常见的 HTTP POST 提
交的报文来理解报文的各个部分与处理器方法参数的对应关系:
请求方法:对应到@RequestMapping 中的 method
请求 URI:中的"/students/create" 对应到@RequestMapping 中的 value 或
者 path
请求头:比如获取 User-Agent 中的值则使用@RequestHeader(“User-Agent”)
来获取
请求参数:比如获取 name 参数的值,则使用@RequestParam(“name”)来获
取。@Controller
@RequestMapping("/students")
public class StudentController {
@RequestMapping(value="/create",method=RequestMethod.POST)
public String create(
@RequestParam(“name”) String name, @RequestParam(“age”) Integer age, @RequestHeader(“User-Agent”) String userAgent){
return null;
}
}
如 果 请 求 参 数 的 名 称 与 处 理 器 方 法 中 的 参 数 名 称 相 同 , 那 么 在 使 用
@RequestParam 绑定的时候,可以省略参数,甚至连@RequestParam 都可
以省略。对于上面的例子,可以写成:
@Controller
@RequestMapping("/students")
public class StudentController {
@RequestMapping(value="/create",method=RequestMethod.POST)
public String create(String name, Integer age){
return null;
}
}
参数列表中还可以直接内置
HttpServletRequest,HttpSession,HttpServletResponse 等对象. 使用 request 对象也可以接收

参数绑定与类型转换
如果请求参数比较多,通常是将这些参数放到一个实体中,然后只需要在处理器
方法上定义这个实体作为参数。HandlerAdapter 会将这个对象的实例创建出
来,然后从请求参数中取出这些参数然后放到实体对象中,需要注意的是请求参
数的名字需要与实体类中的属性一一对应,只有对应的属性才会提取参数的值。
public void edituser(User user){
System.out.println(user);
}
注意到在日期上添加了一个@DateTimeFormat,指定了 Date 类型的格式. @DateTimeFormat(pattern=“yyy-MM-dd”)
private Date birthday;

过滤静态资源文件

<mvc:default-servlet-handler/>

当 DispatcherServlet 的 url 配置为/时 需要添加此配置,能够访问静态资源
例如.jpg,.js,.css 带有后缀名文件。
在 springMVC-servlet.xml 中配置<mvc:default-servlet-handler />后,
会在 Spring MVC 上下文中定义一个
org.springframework.web.servlet.resource.DefaultServletHttpRequest
Handler,它会像一个检查员,对进入 DispatcherServlet 的 URL 进行筛查,
如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的
Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet 继续处理。

中文乱码处理
我们发现在提交请求的时候,如果输入的是中文,处理器方法获取到之后是
乱码。乱码产生的原因在 Java Web 课程中已经讲解过了,解决的方法就是添加
一个过滤器,为 request 对象设置编码集。SpringMVC 中已经为我们提供了这
个过滤器,只需要在 web.xml 中配置好即可:

<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Ajax 返回 JSON
@responseBody 注解的作用是将 controller 的方法返回的对象通过适当的转
换器转换为指定的格式之后,写入到 response 对象的 body 区,通常用来向异
步请求返回 JSON 数据。
注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,
他的效果等同于通过 response 对象输出指定格式的数据。
添加 jacksonjar 包

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>

案例

@PostMapping(path = "/save")
@ResponseBody
public Map save(String name, int age, HttpServletResponse response){
Map map = new HashMap();
try {
map.put("code",200);
map.put("data",new ArrayList<>().add("a"));
map.put("msg","操作成功");
}catch (Exception e){
map.put("code",500);
map.put("msg","操作失败");
}
return map;
}

文件上传
导入上传下载所需 jar 文件

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>

文件解析器

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760"></property>
</bean>

控制器类
@RequestParam(“fileName”) CommonsMultipartFile file 接收文件
file.getOriginalFilename();获得原始文件名
file.getContentType();获得文件类型
file.getInputStream();获得输入流对象

拦截器
SpringMVC 定义了拦截器接口 HandlerInterceptor
该接口中定义了三个方法,这三个方法的调用时在 SpringMVC 框架内部完成的,
调用这个三个方法的时候,其参数的值也是从框架内部传递进来的。
boolean preHandle
预处理方法,实现处理器方法的预处理,就是在处理器方法执行之前这个方法会
被执行,相当于拦截了处理器方法,框架会传递请求和响应对象给该方法,第三
个参数为被拦截的处理器方法。如果 preHandle 方法返回 true 表示继续流程(如
调用下一个拦截器或处理器方法),返回 false 表示流程中断,不会继续调用其
他的拦截器或处理器方法,此时我们需要通过 response 来产生响应;
void postHandle
后处理方法,实现处理器方法的后处理,就是在处理器方法调用完成,但在渲染
视图之前,该方法被调用,此时我们可以通过 modelAndView(模型和视图对
象)对模型数据进行处理或对视图进行处理。
afterCompletion
整个请求处理完毕,即在视图渲染完毕时该方法被执行。

拦截器实现
1.编写一个类,继承 HandlerInterceptorAdapter
public class DemoInterceptor implements HandlerInterceptor{
/* 当请求到达控制器之前被执行
true–继续向下执行,到达下一个拦截器,或控制器
false–不会继续向下执行*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler)throws Exception {
System.out.println(“之前执行”);
return false;
}
/控制器方法执行之后执行/
public void postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler,ModelAndView modelAndView) throws Exception {
System.out.println(“postHandle”);
}
/* 整个请求结束后执行 */
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex)throws Exception {
System.out.println(“afterCompletion”);
}
}
2.注册拦截器

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/statics/**"/>
<mvc:exclude-mapping path="/loginCtl/checklogin"/>
<bean id="demo" class="com.ff.springMVC.util.DemoInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
上一篇:el-table获取表头


下一篇:Spring MVC DispatcherServlet解读