SpringMVC[3]–解决器映射器和适配器

作者 : 开心源码 本文共7996个字,预计阅读时间需要20分钟 发布时间: 2022-05-12 共227人阅读

本文章将从两种配置方式讲起,一般根据项目需求选择合适的方式:

  • 非注解的配置方式(基于XML的资源配置)
  • 注解的配置方式(基于Annotation注解的配置)
    补:注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,以执行相应的解决。

1. 非注解的解决器映射器和适配器

1.1 非注解的解决器映射器(HandlerMapping)

  • BeanNameUrlHandlerMapping
    ?映射规则:将bean的name作为url进行查找,需要在配置Handler时指定bean name(即url)。
    样例:
<!--配置合适的解决器映射器(HandleMapping)--><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><!--可以被url映射的Handler的bean--><bean name="/queryFruits_test.action" class="cn.com.mvc.controller.FruitsControllerTest"/>
  • SimpleUrlHandlerMapping
    ?映射规则:通过内部参数配置请求的url和handler的映射关系。
    样例:
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">    <property name="interceptors">        <list>            <ref bean="someCheckInterceptor1"/>            <ref bean="someCheckInterceptor2"/>        </list>    </property>    <property name="mappings">        <props>            <prop key="user.action">userController</prop>            <prop key="product.action">productController</prop>            <prop key="other.action">otherController</prop>        </props>    </property></bean>

?上面代码中,可以通过property属性配置阻拦器和相关的Handler解决器的URL的映射关系。在样例中增加了两个阻拦器配置,和三个Handler解决器的URl映射。
针对前一篇文章的具体事例:

<!--这里没使用到阻拦器--><bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">    <property name="mappings">        <props>            <prop key="/queryFruits_test.action">fruitsController</prop>        </props>    </property></bean><bean id="fruitsController" class="cn.com.mvc.controller.FruitsControllerTest"/>

访问 localhost:8080/queryFruits_test.action即可以执行对应的controller

  • ControllerClassNameHandlerMapping
    ?映射规则:可以用CoC惯例优先准则(conventionover configuration)的方式来解决请求,对于普通的Controller,会把其类名“xxxController”映射到“/xxx”的请求URL。对于MultiActionController类型的Controller,ControllerClassNameHandlerMapping会把其类名“xxxController”以及其中的方法“yyy”映射到“/xxx/yyy.action”(.action对应设置的dispatcher-servlet的url-pattern)的请求URL。
    样例:
<bean class="org.sprigframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

1.2 非注解的解决器适配器(HandlerAdapter)

  • SimpleControllerHandlerAdapter
    其支持所有实现了Controller接口的Handler控制器。
    例如:
public class FruitsControllerTest implements Controller{    @Override    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {        //模拟Service获取水果商品列表        FruitsService fruitsService = new FruitsService();        List<Fruits> fruitsList = fruitsService.queryFruitsList();        //返回ModelAndView        ModelAndView modelAndView = new ModelAndView();        //相当于request的setAttribut,在JSP页面中通过fruitsList获取数据        modelAndView.addObject("fruitsList",fruitsList);        //指定视图        modelAndView.setViewName("fruitsList");        return modelAndView;    }}
<!--配置解决器映射器(HandleMapping)--><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><!--配置解决器适配器(HandlerAdapter)--><bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">    <property name="mappings">        <props>            <prop key="/queryFruits_test.action">fruitsController</prop>        </props>    </property></bean><bean id="fruitsController" class="cn.com.mvc.controller.FruitsControllerTest"/>

这里例子的详细内容上一节有讲: SpringMVC[2]–框架搭建

  • HttpRequestHandlerAdapter
package cn.com.mvc.controller;import cn.com.mvc.model.Fruits;import cn.com.mvc.service.FruitsService;import org.springframework.web.HttpRequestHandler;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.List;public class FruitsControllerTest2 implements HttpRequestHandler {    private FruitsService fruitsService = new FruitsService();    @Override    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //模拟Service获取水果列表        List<Fruits> fruitsList = fruitsService.queryFruitsList();        //设置模型数据        request.setAttribute("fruitsList",fruitsList);        //设置转发视图        request.getRequestDispatcher("/WEB-INF/jsp/fruitsList.jsp").forward(request, response);    }}

HandlerMapping中增加配置:

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">    <property name="mappings">        <props>            <prop key="/queryFruits_test1.action">fruitsController</prop>            <prop key="/queryFruits_test2.action">fruitsController2</prop>        </props>    </property></bean><bean id="fruitsController" class="cn.com.mvc.controller.FruitsControllerTest"/><bean id="fruitsController2" class="cn.com.mvc.controller.FruitsControllerTest2"/>

访问地址:localhost:8080/queryFruits_test2.action

这里还可以讲List信息拼接为JSON串,而后以JSON格式返回给使用户,并用response的writer对象直接写出返回数据:

package cn.com.mvc.controller;import cn.com.mvc.model.Fruits;import cn.com.mvc.service.FruitsService;import org.springframework.web.HttpRequestHandler;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.List;public class FruitsControllerTest2 implements HttpRequestHandler {    private FruitsService fruitsService = new FruitsService();    @Override    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //模拟Service获取水果列表        List<Fruits> fruitsList = fruitsService.queryFruitsList();        //将fruitsList转换为JSON串        String jsonInfo = convertListToJson(fruitsList);        //设置返回格式        response.setCharacterEncoding("utf-8");        response.setContentType("application/json;charset=utf-8");        //写出JSON串        response.getWriter().write(jsonInfo);    }    private String convertListToJson(List<Fruits> fruitsList){        StringBuilder builder = new StringBuilder();        builder.append('[');        for (Fruits fruits: fruitsList){            builder.append('{');            builder.append("\"name\":\"").append(fruits.getName()).append("\",");            builder.append("\"prive\":\"").append(fruits.getPrice()).append("\",");            builder.append("\"producing_area\":\"").append(fruits.getProducing_area()).append("\"");            builder.append("},");        }        builder.deleteCharAt(builder.length()-1);        builder.append(']');        return builder.toString();    }}

URL请求解决结果.png

注:不在springmvc.xml中设置HandlerMapping和HandlerAdapter,程序仍然会照常运行。其起因是它会默认执行SpringMVC所依赖jar包中的一个默认配置文件DispatcherServlet.properties,其默认映射器为BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping,默认的适配器为HttpRequestHandlerAdapter和AnnotationMethodHandlerAdapter。

2.注解的解决器映射器和适配器

优点:非注解有一个缺陷,就是一个Handler类中只能编写一个方法,这对于大量请求解决逻辑就会捉襟见肘了,而这种问题通过注解的方式即可以轻松处理。

  • Spring3.1之前,SpringMVC的默认注解HandlerMapping和HandlerAdapter分别是:DefaultAnnotationHandlerMappingAnnotationMethodHandlerAdapter,位于org.springframework.web.servlet.mvc.annotation核心包下。
  • Spring3.1之后,之前的默认注解已经被列为过期,基本不再用,其添加了新的基于注解的HandlerMapping和HandlerAdapter,分别是:RequestMappingHandlerMappingRequestMappingHandlerAdapter,位于org.springframework.web.servlet.mvc.method.annotation核心包下

2.1配置注解的解决器适配器和映射器,有两种配置方式:

  • 第一种配置方式
    和之前的非注解配置方式一样,公告相关的bean及实现就可:
<!--注解映射器--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/><!--注解适配器--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
  • 第二种配置方式
    用 <mvc:annotation-driven/> 标签来配置,该标签会自动注册解决器映射器和适配器。
    在实际开发中,为了提高开发效率,用最多的就是annotation-driver标签的配置。
<mvc:annotation-driven/>

2.2 开发Handler解决器层

package cn.com.mvc.controller;import cn.com.mvc.model.Fruits;import cn.com.mvc.service.FruitsService;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import java.util.List;//注解的Handler类//用@Controller来标记它是一个控制器@Controllerpublic class FruitsControllerTest3 {   private FruitsService fruitsService = new FruitsService();   //商品查询列表   //@RequestMapping实现对queryFruitsList方法和url进行映射,一个方法对应一个url   //一般建议url和方法名写成一样   @RequestMapping("/queryFruitsList")   public ModelAndView queryFruitsList() throws Exception{       //模拟Service获取水果商品列表       List<Fruits> fruitsList = fruitsService.queryFruitsList();       //返回ModelAndView       ModelAndView modelAndView = new ModelAndView();       //相当于request的setAttribute,在JSP页面中通过fruitsList获取数据       modelAndView.addObject("fruitsList",fruitsList);       //指定视图       modelAndView.setViewName("fruitsList");       return  modelAndView;   }}

2.3 让注解的HandlerMapping和HandlerAdapter找到注解Handler

有种方式实现,都是在springmvc.xml配置文件中天蝎配置信息:

  • 方法一
<bean class="cn.com.mvc.controller.FruitsControllerTest3"/>
  • 方法二
<context:component-scan base-package="cn.com.mvc.controller"></context:component-scan>

访问地址:localhost:8080/queryFruitsList.action
成功结果:

用注解测试结果.png

注意:假如测试过程中出现“java.lang.IllegalArgumentException”,则说明用了JDK 8.0的环境,因为Spring 3.x版本不支持JDK8.0,因而需要更换编译环境。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » SpringMVC[3]–解决器映射器和适配器

发表回复