深入解析Spring MVC:打造高效优雅的Java Web开发框架

什么是Spring MVC

MVC 模型-视图-控制,用java实现mvc模式的一个web框架。

将复杂的web应用开发简化进行解耦,方便于程序员之间配合开发提高效率。

Spring mvc优点

支持多种视图。ThymeleafView、FreeMarkerView、AbstractPdfView等。

可以天然使用IOC和AOP。

模块分工明确,DispatchServlet 前端控制器、handlerMapping 请求映射处理器、HandlerAdapter 适配器、viewResolver 视图解析器。

DispatcherServlet作用

接收请求、响应结果、组合各模块间的调用

Spring MVC框架的控制器?

控制器就是根据请求路径,访问不通过的处理器最后返回视图。

注解原理是什么

注解本质是一个继承了Annotation的特殊接口,使用注解需要配合java的反射机制完成,相应参数的判断跟功能的增强。

Spring MVC常用的注解

@RequestMapping

@RequestBody

@ResponseBody

SpingMvc中的控制器的注解

@Controller

@RestController

@Controller注解的作用

@Controller 用于标记在一个类上,使用它标记的类就是一个Spring MVC Controller 对象。

@RequestMapping注解

value, method

  1. value: 指定请求的实际地址,指定的地址可以是URI Template
  2. method: 指定请求的method类型, GET、POST、PUT、DELETE等;

consumes,produces

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

params,headers

  1. params: 指定request中必须包含某些参数值。
  2. headers: 指定request中必须包含某些指定的header参数。

@PathVariable和@RequestParam的区别

请求路径上{XXX}变量值,可以通过@PathVariable来获取

@RequestParam用来获得静态的URL请求入参

Spring MVC与Struts2区别

相同点

都是基于mvc的表现层框架,都用于web项目的开发。

不同点

前端控制器不一样。Spring MVC的前端控制器是servlet:DispatcherServlet。struts2的前端控制器是filter:StrutsPreparedAndExcutorFilter。

请求参数的接收方式不一样。Spring MVC是使用方法的形参接收请求的参数,基于方法的开发,线程安全,可以设计为单例或者多例的开发,推荐使用单例模式的开发(执行效率更高),默认就是单例开发模式。struts2是通过类的成员变量接收请求的参数,是基于类的开发,线程不安全,只能设计为多例的开发。

Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,Spring MVC通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

Spring MVC怎么样设定重定向和转发

转发:在返回值前面加"forward:“,例如"forward:XXX.do?XXX=XXX”

重定向:在返回值前面加"redirect:“,例如"redirect:http://XXXX”

转发:由服务器进行页面跳转

重定向:浏览器进行跳转

e46841787cd80d805893c27e68c07657.jpeg

Spring MVC和AJAX 交互

@RequestBody 接收json数据

@ResponseBody 响应JSON数据

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。


请求中文乱码

post请求乱码

web配置文件设置 CharacterEncodingFilter设置为对应的编码格式。

get请求中文参数出现乱码

1.修改tomcat配置文件

Connector标签中,添加 URIEncoding 属性。

2.对参数进行重新编码

new String(xxx.getBytes("旧编码格式"), "新编码格式")

Spring MVC的异常处理

  • @ExceptionHandler-处理局部异常

注意:该注解不是加在产生异常的方法上,而是加在处理异常的方法上。

使用局部异常处理,仅能处理某个 Controller 中的异常。

@ ExceptionHandler 需要进行异常处理的方法必须与出错的方法在同一个 Controller里面。

  • HandlerExceptionResolver-处理全局异常

HandlerExceptionResolver 处理程序异常,包括处理器异常、数据绑定异常以及控制器执行时发生的异常。

实现HandlerExceptionResolver接口,并且将该实现类注册到容器中。

  • SimpleMappingExceptionResolver-处理全局异常

它将异常类名映射为视图名,即发生异常时使用对应的视图作为返回结果。

  • @ControllerAdvice+@ExceptionHandler

@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉。

如何设置请求方式

@RequestMapping注解里面加上method=RequestMethod.GET

Spring MVC 返回值类型

String, ModelAndView

Model、ModelMap和ModelAndView

Model只是用来传输数据的,并不会进行业务的寻址。

ModelAndView 可以进行业务寻址的 。

ModelMap对象主要用于传递控制方法处理数据到结果页面。

注意:Model是每一次请求可以自动创建,但是ModelAndView 是需要我们自己去new的。

ModelMap里面的数据放入Session

类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。

@SessionAttributes(types=XXX.class)会将model中所有类型为 XXX的属性添加到会话中。@SessionAttributes(value={“xxx1”, “xxx2”}) 会将model中属性名为xxx1和xxx2的属性添加到会话中。@SessionAttributes(types={XXX1.class, XXX2.class}) 会将model中所有类型为 XXX1和XXX2的属性添加到会话中。@SessionAttributes(value={“xxx1”,“xxx2”},types={XXX.class})会将model中属性名为xxx1和xxx2以及类型为XXX的属性添加到会话中。

Spring MVC 编写拦截器

两种实现方式:

HandlerInterceptor接口

HandlerInterceptor接口中的方法都是default的,表示不强制重写方法。

但是一般会实现这三个: preHandler、postHandler、afterCompletion

HandleInterceptor拦截器会对请求进行两次拦截:

controller中的void方法会导致springmvc使用你的请求url作为视图名称,然后它在渲染视图之前会检查你的视图名称,发现这视图会导致循环请求,就抛出一个ServletException,tomcat截取到这个异常后就转发到/error页面,就在这个转发的过程中导致了springmvc重新开始DispatcherServlet的整个流程,所以拦截器自然就执行了多次。

在controller(非restController)下:方法返回值类型为String类型或者Void类型(使用请求url作为视图名称),并且不存在对应的视图。都会导致多次拦截。

DispatcherServlet 中applyDefaultViewName(),获取返回值void 获取默认视图名称,默认视图名称就是requestMapping的值。

渲染视图之前springmvc还做了个判断,就是看你的视图名称是不是本次请的uri中的一部分或者和uri一样,如果是的话,就会抛出一个异常,是一个循环视图路径。 InternalResourceView类 prepareForRendering(),会报 ServletExecption。

解决方法:

重写RequestMappingHandlerAdapterViewNameMethodReturnValueHandler这两个类,并将其注入容器中。

ModelAndViewContainer.setRequestHandled(true);//本次请求已经处理完毕,可以直接放行了


WebRequestInterceptor接口

WebRequestInterceptor只有preHandle方法与HandlerInterceptor接口中的preHandle方法不同外,其他都是一样的。

WebRequestInterceptor是spring对HttpServletRequest的封装,所有的更改都会记录在HttpServletRequest中。


小结:

WebRequestInterceptor 和 HandlerInterceptor 中 preHandler方法的区别:

WebRequestInterceptor中该方法只起到对request数据查看修改的作用。preHandle是没有返回值的,说明该方法中的逻辑并不影响后续的方法执行。

HandlerInterceptor 可以根据条件直接返回是否进行拦截(又返回值)。 preHandle方法中就直接拒绝请求进入controller方法。

WebApplicationContext

WebApplicationContext 继承了ApplicationContext,增加了一些web相关的功能。


怎么解决 拦截器拦截 静态资源

preHandler方法中添加下面代码:

if(!(hanlder instanceof HandlerMethod )){ return true;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值