SpringMVC
请求:
@Controller,这个注解和@Service注解意思差不多,都表示该类是一个SpringBean,这样就不需要再在Spring文件中为这个类定义Bean了。
@RequestMapping,用于处理请求映射的,@RequestMapping还可以匹配请求类型,到底是GET还是POST(@RequestMapping(method=RequestMethod.POST));
非debug模式下,方法参数会被编译器优化为其他名字,无法和请求对应,所以最好参数加上@requestparam
小结:
1。假如方法的参数是普通的字符串,只要字符串名字有和请求参数中的key完全匹配的,SpringMVC就会将完全匹配的自动赋值
2.假如方法的参数是实体类,只要实体类中的参数有和请求参数中的key完全匹配的,SpringMVC就会将完全匹配的自动赋值
3.关于并发方面,Servlet是以单实例多线程的方式工作,和每个请求相关的数据都是通过Servlet子类的service方法(或者是doGet或doPost方法)的参数传入的。只要Servlet中的代码只使用局部变量,Servlet就不会导致同步问题。springMVC的控制器也是这么做的,从请求中获得的对象都是以方法的参数传入而不是作为类的成员,很明显Struts2的做法就正好相反,因此Struts2中作为控制器的Action类都是每个请求对应一个实例。
返回数据:
数据如何从后台再次传回前台,答案就是这里要说的Model,关于Model在写例子之前我特别先说明三点:
1、Model本身是一个接口,其实现类为ExtendedModelMap,除了使用Model之外还可以使用ModelAndView、ModelMap这些,不过要是没有特殊需求,使用Model比较简单,我个人也比较喜欢使用Model
2、Model的生命周期是Request,也就是说要通过Model传值只能使用转发而不能使用重定向
3、为什么要使用Model而不是用Request,最主要的原因就是减少代码的侵入性或者说代码的耦合度也行。因为Model是Spring的组件,Request是J2EE的组件,使用Model而不去使用Request可以减少对J2EE的依赖,也便于调试
使用重定向的话(return"redirect:/test.jsp";),要在后台把数据设置到session中,在SpringMVC中,Request、Response、Session、InputStream、OutputStream这些对象是自动注入的,但是就像之前说的,为了减少代码的侵入性与耦合度,能不使用尽量还是不使用这些J2EE的对象的好。
拦截器:
SpringMVC中的拦截器相当于J2EE中的过滤器,是非常重要和相当有用的,它的主要作用就是拦截用户的请求并进行相应的处理的,比如通过它来进行权限验证,或者是来判断用户是否登陆。
在SpringMVC中使用拦截器的方法比较简单,首先实现HandlerInterceptor接口,实现afterCompletion、postHandle、preHandle三个抽象方法。
public class TestInterceptor1 implements HandlerInterceptor { public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("TestInterceptor1.afterCompletion()"); } public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("TestInterceptor1.postHandle()"); } public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("TestInterceptor1.preHandle()"); return true; } } public class TestInterceptor2 implements HandlerInterceptor { public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("TestInterceptor2.afterCompletion()"); } public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("TestInterceptor2.postHandle()"); } public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("TestInterceptor2.preHandle()"); return true; } }
说明一下三个方法的作用:
1、afterCompletion:在整个视图渲染完毕之后执行方法里面的内容,主要用于释放一些资源
2、postHandle:在Controller执行之后,视图渲染之前执行方法里面的内容,也就是说postHandle方法可以对Model进行操作
3、preHandle:在Controller执行之前,执行方法里面的内容,注意该方法是有返回值的,当方法返回false时整个请求就结束了,值得说的是Objectarg2参数,它代表的是被拦截的请求的目标对象,也就是对应请求的controller处理类的对象
然后在springmvc-servlet.xml里面增加拦截器的配置:
<!--配置拦截器-->
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/test" /> <bean class="com.xrq.interceptor.TestInterceptor2" /> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/test" /> <bean class="com.xrq.interceptor.TestInterceptor1" /> </mvc:interceptor> </mvc:interceptors>
假如有多个拦截器的话,”<mvc:interceptor>…</mvc:interceptor>”定义的顺序就是拦截器执行的顺序。
下面继续访问”http://localhost:8080/SpringMVC/test”,代码执行的结果是:
TestInterceptor2.preHandle()
TestInterceptor1.preHandle()
TestInterceptor1.postHandle()
TestInterceptor2.postHandle()
TestInterceptor1.afterCompletion()
TestInterceptor2.afterCompletion()
拦截器和过滤器的区别:
过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大,不只有请求可能会过滤文件
拦截器Interceptor依赖于框架容器,基于反射机制,只过滤请求
相关推荐
@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象进行绑定。加上@ResponseBody注解,就不会走视图解析器,不会返回页面,目前返回的json数据。