Java -- SpringMVC

一、SpringMVC介绍

1. 什么是SpringMVC

  • SpringMVC是一个基于Java实现了MVC设计模式请求驱动类型的轻量级Web框架
  • 把模型-视图-控制器分离,将web层进行职责解耦,简化开发,减少出错,方便开发人员配合
  • Model-View-Controller
    • Model:提供需要展示的数据
    • View:展示的模型
    • Controller:接收请求,委托处理,返回结果(调度器)

2. SpringMVC的优点

  1. 可以支持各种视图技术,不仅局限于JSP
  2. 与Spring框架集成
  3. 角色清晰分配
  4. 支持各种请求资源的映射策略

二、SpringMVC的核心组件

  1. 前端控制器(DispatcherServlet)

    • 作用:接收请求,相应结果,相当于转发调度器
  2. 处理器映射器(HandlerMapping)

    • 作用:根据请求的URL来查找Handler
  3. 处理器适配器(HanderAdaptor)

  4. 处理器(Handler)

    • 需要程序员开发
  5. 视图解析器(ViewResolver)

    • 作用:进行视图解析,将视图的逻辑名解析成为真正的视图
  6. 视图(View)

    • 需要程序员开发
    • 作用:是一个接口,它的实现类支持不同的视图类型

三、SpringMVC工作原理

  1. 用户发送请求至前端控制器(DispatcherServlet)
  2. DispatcherServlet收到请求后,调用处理器映射器(HandlerMapping),请求获取Handle
  3. HandlerMapping根据请求URL找到具体的处理器,生成处理器对象(Handler)及处理器拦截器**(如果有拦截器则生成),将生成结果返回给DispatcherServlet
  4. DispatcherServlet调用处理器适配器(HandlerAdaptor)
  5. HandlerAdaptor经过适配,调用具体的Handler
  6. Handler执行完毕,给HandlerAdaptor返回ModelAndView
  7. HandlerAdaptor将Handler执行结果(ModelAndView)返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给视图解析器(ViewResolver)进行解析
  9. ViewResolver解析后返回具体的View视图
  10. DispatcherServlet对View进行渲染(将模型数据填充至视图中)
  11. DispatcherServlet相应用户

image.png

四、SpringMVC常用注解

  1. @RequestMapping

    • 用于处理请求URL映射
      • 类上:类中所有响应请求的方法都以该地址作为父路径
      • 方法上:该方法以该地址作为路径
    • 六个属性值:
      • value:请求指定实际地址(可以是URI Template)
      • method:请求指定方法
      • consumes:请求提交的内容类型(如html/text、application/josn)
      • produces:返回内容类型,仅当Request请求头中包含指定类型时才返回
      • params:指定Request请求中必须包含某些参数值,否则不处理
      • headers:指定Request请求中必须包含某些指定的header值,否则不处理
  2. @ResquestBody

    • 作用:主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)
    • 原理:josn数据会在Request的请求体中,所以前端不能使用GET方式提交数据,必须使用POST方式提交
    • 使用场景:前端给后端传输的是批量数据(List、Map)等结构时,转换成json再传输
  3. @ResponseBody

    • 作用:将Conreoller方法返回对象转化为json对象响应给客户
    • 原理:通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区
  4. @Controller

    • 作用:注解在类上,表示该类为一个控制器对象
    • 控制器Controller负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model,然后再把该Model返回给对应的View进行展示
    • Spring MVC中提供了一个非常简便的定义Controller的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller标记一个类是Controller,然后使用@RequestMapping和@RequestParam 等一些注解用以定义URL请求和Controller方法之间的映射,这样的Controller就能被外界访问到
    • Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到
  5. @PathVariable

    • 作用:映射URL中的占位符{xxx}到目标方法的参数中(名字不一样时可以进行指定)
    • 主要用于接收Restful风格的请求中的参数
// 前端请求为: .../getUserById/tom
@RequestMapping("/getUserById/{name}")
public User getUser(@PathVariable("name") String userName){
	return userService.selectUser(userName);
}
  1. @RequestParam
    • 作用:将请求参数绑定到你控制器的方法参数上
    • 主要用于接收普通请求中的参数
// 前端请求为: .../getUserById?name=tom
@RequestMapping("/getUserById/{name}")
public User getUser(@RequestParam("name") String userName){
	return userService.selectUser(userName);
}

五、 SpringMVC拦截器

  1. 拦截器作用:

    • 拦截器用于对处理器进行预处理和后处理的技术。
    • 可以定义拦截器链,连接器链就是将拦截器按着顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
    • 依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。
    • 一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理
  2. 自定义拦截器

    • 方法:实现HandlerInterceptor 接口,然后在springmvc.xml中配置拦截器/使用注解将拦截器托管(SpringBoot)
    • 如果定义了多个拦截器,会按照加入的顺序进行拦截
  3. 用例:

  • 自定义拦截器内容:
public class MyInterceptor implements HandlerInterceptor {
    /**
     * 预处理,controller 方法执行前
     * 应用:用于身份认证、身份授权
     * return true 放行,执行下一个拦截器,如果没有,执行 controller 中的方法
     * return false 不放行,即不向下执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    /**
    * 后处理方法,controller 方法执行后,方法跳转 success.jsp 执行之前
    * 应用:从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
    */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    /**
    * success.jsp 页面执行后,该方法会执行
    * 应用:统一异常处理,统一日志处理
    */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}
  • 配置文件配置:
   <!--配置拦截器-->
    <mvc:interceptors>
        <!--配置拦截器,多个拦截器时,顺序执行-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不去拦截的方法
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置拦截器对象-->
            <bean class="com.qf.interceptor.MyInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
  • 注解配置:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    /**
     * 在这里添加自己定义的拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                // 只拦截test路径
        .addPathPatterns("/test/**")
                // 不拦截pass路径
        .excludePathPatterns("/pass/**");
    }
}

六、 Servlet过滤器

  1. 过滤器作用:

    • 使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据;(比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等)
    • 依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次
    • 详解:过滤器详解
  2. 实现方法:

    • 实现Filter接口,定义过滤器功能
    • 配置过滤器(xml配置/注解配置)

Filter的主要的作用就是用户在访问某个目标资源之前,对访问的请求和响应进行拦截,做一些处理,然后再调用目标程序,这样做的好处是可以对一些公共的操作进行抽象,就拿设置字符集来说,如果不使用这种方式,我们每个页面都要写设置字符集的语句。不但麻烦而且维护困难,但是如果使用Filter的话,只需要添加一个类,在xml中配置一下,如果不想使用了,将配置文件中的内容去除即可。Filter基于回调函数,我们需要实现的Filter接口中doFilter方法就是回调函数。

  1. 用例:
  • 过滤器功能:
public class EncodingFilter implements Filter {    

    private String encoding = null;    

    public void destroy() {    
        encoding = null;    
    }    

    public void doFilter(ServletRequest request, ServletResponse response,    
            FilterChain chain) throws IOException, ServletException {    
        String encoding = getEncoding();    
        if (encoding == null){    
            encoding = ”gb2312”;    
        }    
        request.setCharacterEncoding(encoding);//在请求里设置指定的编码    
        chain.doFilter(request, response);  
        //通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源  
    }    

    public void init(FilterConfig FilterConfig) throws ServletException {    
        this.encoding = FilterConfig.getInitParameter(“encoding”);    
    }    

    private String getEncoding() {    
        return this.encoding;    
    }    

}    
  • xml文件配置:
<Filter>    
    <Filter-name>EncodingFilter</Filter-name>    
    <Filter-class>com.logcd.Filter.EncodingFilter</Filter-class>    
    <init-param>    
       <param-name>encoding</param-name>    
       <param-value>gb2312</param-value>    
    </init-param>    
</Filter>    

<Filter-mapping>    
   <Filter-name>EncodingFilter</Filter-name>    
   <url-pattern>/*</url-pattern>    
</Filter-mapping>    
  • 注解配置:
    • 使用注解配置需要在实现Filter类上加@WebFilter,还要再启动类上加@ServletComponentScan
@Configuration
public class WebComponent2Config {
    @Bean
    public FilterRegistrationBean someFilterRegistration1() {
        //新建过滤器注册类
        FilterRegistrationBean registration = new FilterRegistrationBean();
        // 添加我们写好的过滤器
        registration.setFilter(new EncodingFilter());
        // 设置过滤器的URL模式
        registration.addUrlPatterns("/*");
        return registration;
    }

}

七、问题

1. 什么是DispatcherServlet

  • SpringMVC框架是围绕着DispatcherServlet来设计的,DispatcherServlet用来处理所有的HTTP请求和相应

2. 什么是SpringMVC的控制器

  • 控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。Spring用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器。

3. 控制器是不是单例模式

  • 控制器是单例模式
  • 问题:多线程访问时产生线程安全问题
  • 解决:保证控制器是无状态的(控制器中不能有字段)

4. SpringMVC怎么设置转发和重定向

  • 转发:返回值前加forward
  • 重定向:返回值前加redirect

5. SpringMVC中函数的返回值

  • 返回String:
    • 进行视图跳转(视图名称)
    • json字符串传输给前端(@ResponseBody)
  • 返回ModelAndView:
    • 返回模型视图对象(若要返回 ModelAndView,则处理器方法中需要定义 ModelAndView 对象)
    • 使用场景:需要跳转到其它资源,且又要在跳转的资源间传递数据

6. 拦截器和过滤器异同

  • 区别:

    1. 实现机制不同:拦截器是基于Java的反射机制的,而过滤器是基于函数回调
    2. 依赖对象不同:拦截器依赖于Spring/SpringMVC框架,过滤器依赖于servlet容器
    3. 拦截范围不同:拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
    4. 使用资源不同:拦截器也是Spring中的一个组件,因此能够使用Spring中的任何资源、对象,通过IoC注入拦截器即可;而Filter则不能
    5. 作用范围不同:Filter只在Servlet前后起作用,而拦截器能深入到方法前后/异常抛出前后等(优先使用拦截器)
    6. 生命周期不同:在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
  • 相同:

    1. 都是AOP思想的体现
    2. 都能实现权限检查、日志记录等功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值