创建SpringMVC工程流程

注意:SpringMVC框架中有一个Servlet对象:DispatherServlet 把请求转发给Controller对象再处理

1.创建web项目
2.加入依赖
spring webmvc
jsp,servlet
3.在web.xml中注册核心对象DispatcherServlet对象(继承了HttpServlet),负责接收用户提交的请求,调用控制器对象,并把处理结果显示给用户
4.创建请求页面
5.创建控制器类@Controller,放入到SpringMVC容器;
在类的方法上加入@RequestMapping注解
6.创建结果页面
7.创建SpringMVC的配置文件(与spring配置文件一样)
1>声明组件扫描器,指定@Controller所在的包

2>声明视图解析器,帮助处理视图

注意:
如果出现实例化Servlet类[org.springframework.web.servlet.DispatcherServlet]异常

  • 首先打开Prpject Structure–>Artifacts,点开WEB-INF可以发现少了点东西,少了这个存放jar包lib文件夹

image.png

@RequestMapping

加了这个注释,那就代表你是某个Servlet的一个方法. 那么就会将一个请求地址和这个方法绑定,
属性:

  • value = 字符串 , 表示请求url地址,是唯一的不能重复

要注意value的值是数组,也就是说可以存放多个字符串, 使得多个地址对应同一个方法/类

  • method = enum ,表示请求的方法类型(RequestMethod.Get)
  • produces=”text/plain;charset=utf-8”,设置浏览器接受到的响应编码

位置:

  • 方法上方
  • 类上方(当放在类上方时,value的值的作用是自动给方法的value前加上这个值,也就是省去了公共部分)

注意:

  • 加了这个注释的方法的返回值:ModelAndView
    • Model:数据,请求处理完要显示给用户的数据
    • View:视图,比如Jsp等
  • 返回了ModelAndView之后,才会根据ModelAndView中的内容执行操作

ModelAndView

  • .addObject(String,Object):相当于在请求的最后,把数据放入到request作用域中
  • .setViewName(String):指定完整的视图路径,框架执行的相当于是对视图进行forward操作

视图配置

  • 在spring.xml中配置





这样就指定了/WEB-INF/目录下的所有jsp文件为视图,当我们需要使用这个目录下的这些视图时,不再输入完整路径名,而只要输入视图的文件名就行了

参数

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • 请求参数(形参名必须与请求参数名称一致)
  1. 当使用post接受参数时,会出现中文乱码现象。应当使用过滤器解决这个问题。这个过滤器叫做CharacterEncodingFilter

过滤器例子:

characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter

encoding
utf-8


forceRequestEncoding
true


forceResponseEncoding
true


characterEncodingFilter
/*

  1. 如果请求参数名和处理器方法形参名不一样,则需要@RequestParam(value = “请求参数名” ,required = “true”)来加以解释,其中required的默认值为true,指的是默认必须要有参数,否则报错。
  1. 当请求中参数过多时,直接在形参中加入显得非常臃肿,编写效率低,此时,可以讲请求参数值接受到对象中去。此时,处理器方法的形参应该为Java对象,这个对象的属性名和请求中属性名一样。框架会创建形参的java对象,给属性赋值(调用set方法)。形参中可以有多个对象,框架会依次将请求参数中的值赋给这些对象。

处理器方法,除了ModelAndView的返回值类型

除了ModelAndView,还有以下三大返回值:

  • String
  • void
  • Object

当返回值为String时,String值为视图名,即可跳转到该视图界面(不会给页面传递参数,如果要传递数据,则需要用request.setAttribute()手动添加数据)
当返回值为void时,什么也不会返回,可以用来输出数据响应ajax请求(只返回数据,没有视图),通常会用到Json格式,依赖包为Jackson
当返回值为Object时(相当于也是返回数据),响应ajax请求
现在做ajax,主要使用json格式:

  1. 1. 加入依赖,springmvc默认使用jackson
  2. 1. springMvc.xml中加入<mvc:annocation-driven>注解驱动
  3. 1. 在处理器方法上加入@ResponseBody注解

原理:
1.
注解驱动实现的功能是:完成Java对象到json、xml、text、二进制等数据格式的转换(实际上是创建了7种HttpMessageConverter的实现类)
HttpMessageConverter接口:消息转换器
功能:定义了java转为json、xml等数据格式的方法。这个接口有很多的实现类。这些实现类完成了java对象到json、xml、二进制的转化。

下面两个方法是处理器类把结果输出给浏览器时使用的:
boolean canwrite(Class<?> var1,@Nullable MediaType var2)
void write(T var1,@Nullable MediaType var2,HttpOutputMessage var3)
canwrite()方法:判断某个对象(例如student(zhangsan,20))能不能转换为var2表示的数据格式的。能则返回true
其中的MediaType是表示某种数据格式(比如json,form表单,xml,stream,pdf)
write()方法:将处理器返回的对象转化为某个数据格式。
2.注解@ResponseBody
放在处理器方法上方,通过HttpServletResponse输出数据,响应ajax请求(其实就是创建输出,并通过response输出数据(某种格式)。)
response.getWriter().write( )

当我们将DispatcherServlet的访问路径改为/ 时

会出现静态资源不能访问的情况。原因是:
原本静态资源是交给Tomcat中的DefaultServlet处理的,路径为/ 。如果我们将DispatcherServlet的路径改为/ ,那么就会覆盖掉原本访问DefaultServlet的路径,故而不能访问静态资源了。
解决办法:
1.在SpringMVC.xml文件中,添加新的对象 ,这样静态资源就会交给它来处理了。但是,这个对象和@RequestMapping注解有冲突,会导致所有动态资源都会走默认处理器,进而导致动态资源不能访问,此时需要添加注解驱动来解决这个问题:,ok。
2.在SpringMVC.xml文件中,添加新的对象,其中mapping指的是访问的uri地址,location是资源位置。 其中,访问地址例子:/image/**(匹配image下的任意文件),location=/image/。

当返回ModelAndView的同时,如何使用重定向或者转发?

转发:setViewName(“forward:地址”)
重定向:setViwName(“redirect:地址”)
注意:view中,在Request域中的内容用${requetsScope.参数名}取出;在请求参数中的内容用${param.参数名}取出,或者<%=request.getParameter(“参数名”)%>

如何处理异常?

  • 新建一个异常类,再定义它的子类
  • 在Controller中抛出异常
  • 创建一个普通类,作用全局异常处理类
    • 在类的上方加入@ControllerAdvice
    • 在类中定义方法,方法上方加入@ExceptionHandler
  • 创建处理异常的页面
  • 创建SpringMVC的配置文件
    • 组件扫描器,扫描@Controller注解
    • 组件扫描器,扫描@ControllerAdvice所在的包名
    • 声明注解驱动

@ControllerAdvice

控制器增强,赋予了新的功能—异常处理功能

  • 特点:必须让框架指导这个注解所在的包名,需要在SpringMVC配置文件中声明组件扫描器
  • 其中的方法的特点:
    • 可以有多个参数,可以有多个返回值(ModelAndView等)
    • 形参:Exception,表示Controller抛出的异常对象,可以获取到异常信息

@ExceptionHandler

用在异常处理器的方法上

  • 格式:@ExceptionHandler(异常的class),表示发生此类型异常时,执行此方法
  • 通常异常处理逻辑:
    • 记录异常到数据库,日志文件
    • 发送异常通知(邮件,短信,微信)
    • 给用户友好的提示

拦截器

  • 拦截器是SpringMVC中的一种,需要实现HandlerIntercept接口。
  • 和过滤器类似,侧重点不同。过滤器是过滤请求参数,设置字符编码等。拦截器是拦截用户请求,做请求判断。
  • 拦截器是全局的,可以对多个Controller做拦截。拦截器可以有多个,共同拦截请求。
  • 常用在:权限检查,记录日志

使用步骤:

  • 定义HandlerInterceptor接口
  • 在SpringMVC配置文件中,声明拦截器

执行时机:

  • 在请求处理之前,也就在处理器方法执行前被拦截
  • 在处理器方法执行之后也会执行拦截器
  • 在请求处理完成后也会执行拦截器

实现步骤:

  • 创建普通类,实现HandlerInterceptor接口,实现接口方法。
  • 创建视图
  • 创建SpringMVC配置文件
    • 组件扫描器,扫描@Controller
    • 声明拦截器,并指定拦截的URI地址

注意:

  • preHandler方法介绍:
    • 参数request,response,Object handler
    • handler:被拦截的控制器对象
    • 返回值boolean类型
    • 特点:在处理器方法之前执行
  • postHandler方法介绍:
    • 参数handler,mv
    • handler:处理器对象
    • mv:处理器方法返回值ModelAndView
    • 特点:
      • 在处理器方法执行之后执行
      • 能获取到mv,可以修改mv中的m和v,可以影响到最后的结果
      • 主要用来对原来的执行结果进行修正
  • afterCompletion方法介绍:
    • 参数handler,ex
    • handler:处理器对象
    • ex:发生的异常对象
    • 特点:
      • 在请求处理完成后执行。即完成了视图的forward。
      • 一般是做资源回收的

SpringMVC中的拦截器例子:





当有多个拦截器时:
先配置的拦截器先执行preHandler,再执行后配置的拦截器的preHandler
然后以后递归的形式,先执行后配置的postHandler,再执行先配置的postHandler方法
afterCompletion方法也是后递归形式

拦截器和过滤器的区别

  1. 过滤器是Servlet中的对象,拦截器是SpringMVC中的对象
  2. 过滤器实现Filter接口,拦截器实现HandlerInterceptor接口
  3. 过滤器是用来设置request,response的参数等属性的,侧重对数据的过滤。拦截器是验证请求的。
  4. 过滤器是在拦截器之前执行的。
  5. 过滤器是Tomcat创建的,拦截器是SpringMVC创建的
  6. 过滤器只有一个执行时机,拦截器有三个
  7. 过滤器可以处理jsp,js,html等。拦截器是拦截对处理器的请求。