1.SpringMVC框架
1.1什么是springmvc
springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。
springmvc是一个基于mvc的web框架
1.2mvc在b/s系统下的应用
mvc是一个设计模式,mvc在b/s系统下的应用:
1.3springmvc框架
2.入门程序
2.1配置前端控制器
2.2配置处理映射器
因为对于用户发起的request请求,前端控制器首先会请求HandlerMapping处理器映射器来查找Handler,所以我们首先配置它,在springmvc.xml中加入如下内容:
<!--配置处理器映射器
springmvc框架根据HandlerMapping接口判断是否是处理器映射器-->
<!--根据bean的name进行查找Handler,将action的url配置在bean的name中-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
BeanNameUrlHandlerMapping
:表示将定义的Bean名字作为请求的url,需要将编写的controller在spring容器中进行配置,且指定bean的name为请求的url,且必须以.action结尾。
2.3配置处理器适配器
处理器映射器将查找到的Handler返回给DispatcherServlet后,DispatcherServlet会调用适配器执行Handler,通过适配器去扩展对不同Handler的执行。所以我们再配置它,在springmvc.xml中国年添加如下内容:
<!--配置处理器适配器
springmvc框架根据HandlerAdapter接口判断是否是处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
SimpleControllerHandlerAdapter
:即简单控制器处理适配器,所有实现了org.springframework.web.servlet.mvc.Controller
接口的Bean作为Springmvc的后端控制器。
###2.4后端控制器的编写
package controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import po.Items;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by codingBoy on 16/11/13.
*/
public class ItemController1 implements Controller
{
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception {
//使用静态的数据将商品信息显示在jsp页面
List<Items> itemsList = new ArrayList<>();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("itemsList",itemsList);
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");//指定用户访问的jsp页面地址
return modelAndView;
}
}
2.5后端控制器的配置
在springmvc.xml中配置Handler由spring来管理Handler,在springmvc.xml文件中添加如下内容:
<!--配置Handler
由于使用了BeanNameUrlHandlerMapping处理映射器,所以name要配置为url-->
<bean name="/itemList.action" class="controller.ItemController1"></bean>
name="/itemsList.action"
:前边配置的处理器映射器为BeanNameUrlHandlerMapping
,如果请求的URL为“上下文/itemsList.action”将会成功映射到ItemController1控制器。
2.6配置视图解析器
Handler执行完成后给处理器适配器返回一个ModelAndView对象,它是Spring MVC的一个对象,用于对Model和View进行封装。然后处理器适配器又将这个对象返回给DispatcherServlet,DispatcherServlet调用视图解析器进行视图解析,所以这里我们要配置视图解析器,在springmvc.xml中添加如下内容:
<!--配置视图解析器
要求将jstl的包加到classpath-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
</bean>
有了前缀与后缀以后,可以省略相应的路径使得控制器里ViewName少写一点,更加简洁。
3.非注解的处理器映射器和适配器
3.1BeanNameUrlHandlerMapping(映射器)
就是上文中我们用到的处理器映射器,根据请求url(XXXX.action)匹配spring容器bean标签的name属性找到对应的Handler(通过class属性找到程序员编写的那个Handler)。
3.2SimpleUrlHandlerMapping(映射器)
简单url映射器,是BeanNameUrlHandlerMapping的增强版,在springmvc.xml配置文件中这样配置SimpleUrlHandlerMapping:
<!--简单url映射
几种配置bean的id对应的url
key:用户请求的url
标签内容:程序员编写的Handler在此配置文件中的id-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/items1.action">itemController1</prop>
<prop key="/items2.action">itemController1</prop>
</props>
</property>
</bean>
SimpleUrlHandlerMapping的配置中需要用到Handler在springmvc.xml中的配置id,所以这里我们需要给Handler的配置加上一个标签:
<!--配置Handler
由于使用了BeanNameUrlHandlerMapping处理映射器,所以name要配置为url。另外不需要id属性-->
<bean id="itemController1" name="/itemList.action" class="controller.ItemController1"></bean>
此时两个处理器映射器对应三个不同的url地址,但却指向的是同一个Controller(即Handler),运行程序,发现输入http://localhost:8080/SpringMvc/itemList.action
或http://localhost:8080/SpringMvc/items1.action
或http://localhost:8080/SpringMvc/items2.action
访问的都是同一个页面,说明:若在springmvc.xml配置文件中配置了多个处理器映射器,多个映射器可以共存。
3.3SimpleControllerHandlerAdapter(适配器)
就是上文中我们用到的处理器适配器,要求前端控制器通过这个适配器找到的Handler(Controller)需要实现 Controller接口。
3.4HttpRequestHandlerAdapter(适配器)
HttpRequestHandlerAdapter在配置文件中这样配置:
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
要求前端控制器使用这个适配器找到的Handler需要实现HttpRequestHandler接口。
使用这个适配器开发的Handler代码为:
public class ItemController2 implements HttpRequestHandler
{
@Override
public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
//使用静态的数据将商品信息显示在jsp页面
List<Items> itemsList = new ArrayList<>();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
httpServletRequest.setAttribute("itemsList",itemsList);
httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(httpServletRequest,httpServletResponse);
//使用此方法可以通过修改response,设置相应的数据格式,比如相应json数据
/*
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter.write("json串");
*/
}
}
实现HttpRequestHandler需要实现的方法返回值为void,不能给处理器适配器返回ModelAndView对象,所以代码中我们要使用request域进行注入值。
然后是Handler在springmvc.xml中的配置,这里我们让该Handler使用SimpleUrlHandlerMapping处理器映射器,所以不需要给该Handler设置name:
<bean id="itemController2" class="controller.ItemController2"></bean>
然后修改SimpleUrlHandlerMapping在配置:
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/items2.action">itemController2</prop>
</props>
</property>
</bean>
4.DispatcherServlet.properties
前端控制器从 上边的文件中加载处理器映射器、适配器、视图解析器等组件,如果不在springmvc.xml中配置,使用默认加载的。
5.注解的处理器映射器和适配器
5.1注解的处理器映射器
在spring3.1版本之前,系统默认加载DispatcherServlet.properoties文件中的org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
注解映射器,3.1版本之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
这个注解映射器。在springmvc.xml中进行RequestMappingHandlerMapping的配置:
<!--注解处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
使用RequestMappingHandlerMapping需要在Handler 中使用@controller标识此类是一个控制器,使用@requestMapping指定Handler方法所对应的url。
5.2注解的处理器适配器
pring3.1之前默认加载DispatcherServlet.properoties中的注解适配器是
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
,3.1版本之后要使用:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
这个注解适配器。在springmvc.xml中进行如下配置:
<!--注解的适配器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
RequestMappingHandlerAdapter,不要求Handler实现任何接口,它需要和RequestMappingHandlerMapping注解映射器配对使用,主要解析Handler方法中的形参。
5.3实际开发中注解处理器映射器和处理器适配器配置
5.4注解开发Handler
利用注解开发的Handler不需要实现任何接口,java代码为如下:
@org.springframework.stereotype.Controller
public class ItemController3
{
//商品列表:@RequestMapping中url建议和方法名一样,方便开发维护
@RequestMapping("/queryItems")
public ModelAndView queryItems() {
//使用静态的数据将商品信息显示在jsp页面
List<Items> itemsList = new ArrayList<>();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setCreatetime(new Date());
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("itemsList",itemsList);
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
return modelAndView;
}
}
然后在springmvc.xml中对该Handler进行配置:
<!--注解的Handler
不用id,url在@RequestMapping注解中已经声明-->
<bean class="controller.ItemController3"/>
上面我们通过对单个注解Handler的配置,也可以使用组件扫描<context:component-scan base-package="包名"/>
对整个包下的Handler进行配置。
然后运行服务器输入网址http://localhost:8080/SpringMvc/queryItems.action
,正常访问,这里的url为@RequestMapping中的参数。组件扫描还可以可以扫描@Controller、@Service、@component、@Repsitory。
6.源码分析
- 前段控制器接受请求
2. 调用处理器映射器查找Handler
-
调用处理器适配器执行Handler,得到执行结果ModelAndView
-
视图渲染,将model数据填充到request域
视图解析:
视图渲染: