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依赖于框架容器,基于反射机制,只过滤请求

相关推荐