2、处理器映射器和适配器、视图解析器(springMVC笔记)

一、非注解映射器和适配器(工程springMVC02

1.1 非注解映射器

  • 非注解映射器BeanNameUrlHandlerMapping
    在之前我们使用的是这个处理器映射器,配置为:

使用此映射器的时候是将bean的名字作为url进行查找,需要在配置Handler时指定bean的名字(就是url


  • 非注解映射器SimpleUrlHandlerMapping
    从上面的配置可以看到,如果控制器较多的时候便不是很方便了,于是看使用此种非注解映射器如何配置:
    
        
            
                
                itemsController1
                itemsController1
                
                itemsController2
            
        
    

使用此种映射器的时候一个控制器可以对应多个url,可以看到我们可以同时为多个控制器配置url,较为方便。这里注意:我们使用中的key指定url,其值即是相关控制器的id,但是使用此映射器的时候,配置控制器时则不需要指定name属性了。

1.2 非注解适配器

  • 非注解适配器SimpleControllerHandlerAdapter
    我们看相关的配置:

而使用此配置器时,相关的控制器需要实现Controller接口,我们看相关的类实现ItemsController1.java

package cn.itcast.ssm.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import cn.itcast.ssm.pojo.Items;

//实现Controller接口的映射器
public class ItemsController1 implements Controller{

    @Override
    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        //调用service查询数据库,查询商品列表,这里使用静态数据库模拟
        List itemsList = new ArrayList();
        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(6000f);
        items_1.setDetail("ThinkPad T 430");
        
        Items items_2 = new Items();
        items_2.setName("苹果手机");
        items_2.setPrice(5000f);
        items_2.setDetail("iphone6s");
        
        itemsList.add(items_1);
        itemsList.add(items_2);
        
        //返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        //相当于request的setAttribute方法,在jsp页面中就可以通过items取数据了
        modelAndView.addObject("itemsList",itemsList);
        
        //指定视图
        modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
        
        return modelAndView;
    }
}

这个类其实我们在之前的工程中已经给出了。

  • 非注解适配器HttpRequestHandlerAdapter

使用此适配器的控制器需要实现HttpRequestHandler接口,当然映射器可以任选。这里我们给出相关的类ItemsController2.java

package cn.itcast.ssm.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import cn.itcast.ssm.pojo.Items;

//实现Controller接口的映射器
public class ItemsController2 implements HttpRequestHandler{

    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        List itemsList = new ArrayList();
        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(6000f);
        items_1.setDetail("ThinkPad T 430");
        
        Items items_2 = new Items();
        items_2.setName("苹果手机");
        items_2.setPrice(5000f);
        items_2.setDetail("iphone6s");
        
        itemsList.add(items_1);
        itemsList.add(items_2);
        
        request.setAttribute("itemsList",itemsList);
        //视图
        request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
        /*
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write("json串");
        */
        
    }
}

注意:这种方式看起来很原始,但可通过response修改定义响应的内容,比如返回json数据。在上面我们已经给出相关的代码。
注意:这里我们配置多个适配器和映射器是不会冲突的。因为这里的映射器和适配器都是非注解的。

二、注解映射器和适配器(工程springMVC03

2.1 相关说明

  • 1.非注解的多个映射器或适配器不会冲突,但是却不能和注解的适配器同时使用,必须要成对,即注解的适配器必须使用注解的映射器。
  • 2.我们发现在上一个工程中我们将相关映射器和适配器删掉之后工程还是可以运行的,这是因为springMVC中有默认的配置,我们在包中找到一个资源文件:
    2、处理器映射器和适配器、视图解析器(springMVC笔记)_第1张图片
    1

    前端控制器会从配置文件中加载处理器映射器、适配器、视图解析器等组件,如果不再配置文件中配置这些组件,那么就使用DispatcherServlet.properties中默认的配置。

2.2 注解的映射器和适配器



说明:这里我们分别配置了注解形式的映射器和适配器,当然springMVC给我们提供了更好用的工具,使用下面的配置我们就可以将上面的配置取消掉了:


说明:我们在使用此配置的时候报错很可能是schema文件没有配置上,在后面我们会给出完整的配置文件,可以自行查看。其实在开发中也是使用此种方式。

2.3 控制器编写

使用注解的方式,当然控制器的编写也是不一样了,我们发现在使用非注解的方式时编写控制器总是要继承相关的接口,那必然就要实现相关的方法,那如果我们想编写多个方法就不是很方便了,这里我们看注解方式可以很好的改善这一问题:
ItemsController3.java

package cn.itcast.ssm.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import cn.itcast.ssm.pojo.Items;

//注解的handler
/*使用@Controller标识控制器*/

@Controller
public class ItemsController3{
    
    //商品查询列表,一般建议将url和方法名一样,@RequestMapping实现对下面方法和url进行映射,
    //即一个方法对应一个url,url后面可以加.action也可以不加
    @RequestMapping("/queryItems")
    public ModelAndView queryItems() throws Exception{
        List itemsList = new ArrayList();
        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(6000f);
        items_1.setDetail("ThinkPad T 430");
        
        Items items_2 = new Items();
        items_2.setName("苹果手机");
        items_2.setPrice(5000f);
        items_2.setDetail("iphone6s");
        
        itemsList.add(items_1);
        itemsList.add(items_2);
        
        //返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        //相当于request的setAttribute方法,在jsp页面中就可以通过items取数据了
        modelAndView.addObject("itemsList",itemsList);
        
        //指定视图
        modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
        
        return modelAndView;
    }
    //其他方法也可以同时在此类中进行添加
}

说明:这里我们使用注解@Controller表示此类是一个控制器,使用注解@RequestMapping表示其对应的url。同时我们可以看到不需要继承任何接口,于是我们可以在此类中定义多个方法,而相关的url映射使用注解即可。

2.4 配置控制器






说明:这里我们给出了两种配置方法,当然如何取舍我们在配置中已经注明。最后我们可以使用地址http://localhost:8080/springMVC03/queryItems.action进行访问。不管url中有没有.action,都使用上面的地址。

三、视图解析器

视图解析器默认是支持jstl的,但是在配置的时候我们还可以为跳转的jsp地址配置前缀和后缀:

    
        
        
        
        
        
        
    

这里我们配置了前缀和后缀,那么在控制器ItemsController3.java中进行跳转的时候就可以这样:

modelAndView.setViewName("items/itemsList");

最后:给出完整的配置文件springmvc.xml



    
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    
        
        
        
        
        
        
    

四、跟踪源码

这里我们只是简要的跟踪一下源码,加深对springMVC执行流程的认识。

  • 1.前端控制器
    这里当然我们首先供前端控制器开始,此类中有一个入口方法doDispatch(),我们从此方法开始。

  • 2.前端控制器调用映射器查找控制器
    我们在doDispatch()中找到这样一段

    2、处理器映射器和适配器、视图解析器(springMVC笔记)_第2张图片
    2

    这里我们进入getHandler方法:
    2、处理器映射器和适配器、视图解析器(springMVC笔记)_第3张图片
    3

    可以看到此方法返回一个执行链HandlerExecutionChain

  • 3.调用处理器处理器调用handler
    映射器返回执行链之后前端加载器就会调用处理器去处理相关方法,在doDispatch()方法中找到:

    4

    我们进入此方法的时候发现出现了很多适配器,我们在之前都见过,它们在执行完之后都会返回一个ModelAndView

  • 4.视图渲染,将model数据填充到request
    doDispatch()方法中找到

    5

    进入此方法,在此方法中找到:
    6

    7

    可以看到调用的是render方法,得到一个view,再调用view的渲染方法,将model数据填充到request域中。在前端控制器类render()方法中找到:
    8

    此类是一个接口,我们进入其抽象方法
    9

    再次进入,可以看到:
    2、处理器映射器和适配器、视图解析器(springMVC笔记)_第4张图片
    10

    进入方法renderMergedOutputModel

2、处理器映射器和适配器、视图解析器(springMVC笔记)_第5张图片
11

这里我们可以看到很多渲染类,之前我们配置了一个 InternalResourceViewResolver,选择 InternalResourceView,看到下面这段代码:
12

点击进入:
13

这里就将模型数据填充到了视图类中。

你可能感兴趣的:(2、处理器映射器和适配器、视图解析器(springMVC笔记))