目录
1.2.1 BeanNameUrlHandlerMapping
1.非注解
1.1非注解的处理器适配器
<!-- 非注解的处理器适配器 -->
<!-- 要求编写的Handler 实现Controller接口-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 另一个非注解的适配器 -->
<!-- 要求编写的Handler 实现HttpRequestHandler接口-->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
二者都要求实现HandlerAdapter接口,SimpleControllerHandlerAdapter我们可以观察其源码
可以发现其实现了HandlerAdapter接口,并且我们可以根据它返回的值,可以确定我们编写的Handler要实现controller的接口。Handler实例如下。
//实现controller接口的处理器
public class ItemController1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
//调用service查找数据库,查询商品列表,这里使用静态数据模拟
List<Items> itemsList = new ArrayList<Items>();
//向list中添加静态数据
Items item_1 = new Items();
item_1.setName("小米手机");
item_1.setPrice(1600f);
item_1.setDetail("小米8青春版");
Items item_2 = new Items();
item_2.setName("华为手机");
item_2.setPrice(1700f);
item_2.setDetail("华为P30");
itemsList.add(item_1);
itemsList.add(item_2);
//返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
//相当于request的setAttribute,在jsp页面中通过itemsList添加数据
modelAndView.addObject("itemsList", itemsList);
//指定视图
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
}
接着我们继续看一下HttpRequestHandlerAdapter的源码
同样的实现了HandlerAdapter接口,根据其返回值我们也可以知道编写的handler要实现HttpRequestHandler接口 ,这里我放一个Handler实例给大家参考
//实现HttpRequestHandler接口的处理器
public class ItemController2 implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//调用service查找数据库,查询商品列表,这里使用静态数据模拟
List<Items> itemsList = new ArrayList<Items>();
//向list中添加静态数据
Items item_1 = new Items();
item_1.setName("小米手机");
item_1.setPrice(1600f);
item_1.setDetail("小米8青春版");
Items item_2 = new Items();
item_2.setName("华为手机");
item_2.setPrice(1700f);
item_2.setDetail("华为P30");
itemsList.add(item_1);
itemsList.add(item_2);
//设置模型数据
request.setAttribute("itemsList", itemsList);
//设置转发视图
request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
//使用此方法可以通过修改response,设置响应的数据格式,比如响应json数据。
//response.setCharacterEncoding("utf-8");
//response.setContentType("application/json;charset=utf-8");
//response.getWriter().write("json串");
}
}
1.2非注解的处理器映射器
非注解的处理器映射器也存在俩种情况,一种是BeanNameUrlHandlerMapping,另一种是SimpleUrlHandlerMapping。现在我们根据这俩种展开分析。
1.2.1 BeanNameUrlHandlerMapping
配置好一个Handler
<!-- 配置Handler -->
<bean id="itemController1" name="/queryItems_1.action" class="cn.itcast.ssm.controller.ItemController1"/>
接着我们继续配置非注解的处理器映射器
<!--非注解的处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url)
所有的映射器都实现 HandlerMapping接口。 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
可以看出此映射器所需要的是在配置Handler的时候把name配置上访问的url地址,这样一个非注解的处理器映射器就配置好了。
1.2.2 SimpleUrlHandlerMapping
第一步还是先配置Handler
<!-- 配置Handler -->
<bean id="itemController2" class="cn.itcast.ssm.controller.ItemController2"/>
接着继续配置映射器
<!--简单url映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- 值是bean的id ,key就是访问的url地址 -->
<prop key="/queryItems1.action">itemController2</prop>
<prop key="/queryItems2.action">itemController2</prop>
</props>
</property>
</bean>
从配置我们可以看出此时配置Handler的name就显得不重要了,需要配置好其id,从中也可以看出一个controller可以对应多个url与之映射。
1.3 总结
多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。而且发现处理器映射器就是:根据我们的 URL 寻找 Handler。处理器适配器就是:按照它要求的规则去执行 Handler。非注解形式的HandlerMapping和HandlerAdapter 所对应的 Handler,一个类中只有一个方法,处理能力有限,比较繁琐。
2.注解
注解的处理器适配器和处理器映射器在开发中就比较适用了。而且配置也比较简单,首先还是看Handler的配置。
<!-- 对于注解的Handler可以单个配置
实际开发中使用扫描组件
-->
<!-- bean class="cn.itcast.ssm.controller.ItemController3" -->
<!-- 可以扫描Controller,service...
这里让组件扫描Controller,指定Controller包
-->
<context:component-scan base-package="cn.itcast.ssm.controller">
</context:component-scan>
可以单个配置,可以看见少了id和name的属性配置,但是比较繁琐,一般都采用组件扫描的方式。
接着继续处理器映射器和处理器适配器的配置
<!-- 注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--使用mvc:annotation-driven可以代替上面注解映射器和注解适配器的配置
mvc:annotation-driven默认加载了许多参数绑定的方法,比如json转换的解析器默认加载了。
实际开发用此种方法
-->
<mvc:annotation-driven></mvc:annotation-driven>
可以看见这种也有通用方法配置<mvc:annotation-driven></mvc:annotation-driven>实际开发中采用这种方式。通过注解的方式是不是使代码简便的许多。我们再来看看controller的书写。
//注解的controller
@Controller
public class ItemController3 {
//注解的映射器
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws Exception{
//调用service查找数据库,查询商品列表,这里使用静态数据模拟
List<Items> itemsList = new ArrayList<Items>();
//向list中添加静态数据
Items item_1 = new Items();
item_1.setName("小米手机");
item_1.setPrice(1600f);
item_1.setDetail("小米8青春版");
Items item_2 = new Items();
item_2.setName("华为手机");
item_2.setPrice(1700f);
item_2.setDetail("华为P30");
itemsList.add(item_1);
itemsList.add(item_2);
//返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
//相当于request的setAttribute,在jsp页面中通过itemsList添加数据
modelAndView.addObject("itemsList", itemsList);
//指定视图
//modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
//上面的jsp路径如果在spring.xml文件中配置了可以改为如下代码
modelAndView.setViewName("items/itemsList");
return modelAndView;
}
}
在书写controller时要用到俩个注解,一个是@Controller说明其是一个Controller,另一个是@RequestMapping指定访问的url,这样我们在一个类中可以书写多个方法了。