- SpringMVC简介
- SpringMVC核心配置
- Controller
- ModelAndView
一、简介
SpringMVC是当前最优秀的MVC框架,自2.5版本后,开始支持注解。
SpringMVC与Struts区别:前者采用了原始的el,jstl表达式,页面效率高与后者(采用了值堆栈、strts标签库、ognl表达式)相比,更高。
后者有可插拔式的、灵活的拦截器;有线程安全的action。同时SpringMVC也具有这些特性。
二、核心
2.1、SpringMVC架构
SpringMVC是结构最清晰的MVC Model2 实现。它的Action称作Controller,Controller接收request,response参数,然后返回ModelAndView(其中的Model不是Object类型,是Map类型)。
在其它框架中,Action返回值一般都是一个ViewName;Model则需要通过其它的途径(如request.attribute,Context参数,或 Action本身的属性数据)传递上去。
2.2、SpringMVC请求流程
- SpringMVC 所有请求都是交给DispatherServlet,它委托应用系统的其他模块负责对请求进行处理。
- DispatherServlet 查询一个或多个HandlerMapping,找到处理请求对应的Controller
- DispatherServlet 将请求提交给目标controller
- Controller进行业务逻辑处理后,返回一个ModelAndView
- Dispather查询一个或多个ViewResolve视图解析器,找到ModelAndView对象指定的对象。
- 视图对象负责渲染返回给客户端。
三、配置
3.1、配置DispatherServlet
Dispather是SpringMVC请求的中枢,继承了HttpServlet,是一个Servlet,由WebApplicationContext加载。
在web.xml中配置DispatherServlet
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置拦截内容,/会拦截所有,包括静态文件,后面给出解决方案-->
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3.2、配置SpringMVC.xml
<!--注意添加xmlns文件和xsd文件-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 默认扫描包 -->
<context:component-scan base-package="com.it.springmvc"/>
<!--默认注解映射的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 视图解析器 -->
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 对静态资源的访问 方案一 (二选一) -->
<mvc:default-servlet-handler/>
<!-- ... -->
<!--对静态资源的访问 方案二 (二选一)-->
<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>
<mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>
<mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>
</beans>
3.3、<context:compont-scan/>
扫描指定包中的类上的注解,常用的注解有
@Controller 声明Action组件
@Service 声明Service组件 @Service("myMovieLister")
@Repository 声明Dao组件
@Component 泛指组件
@RequestMapping("/menu")请求映射
@Resource 用于注入,默认按名称装配 @Resouce(name="beanName")
@Autowired 用于注入,默认按类型装配
@Transactional(rollbackFor={Exception.class})事务管理
@ResponseBody
@Scope("prototype")设定的bean的作用域
3.4、HandlerMapping
将web请求映射到正确的处理器(handler)上,通常是一个Controller。有三种
BeanNameUrlHandlerMappiing:Bean的name对应的Handler就是这个url请求对应的Handle
<bean name="/test" class="com.controller.HelloController"/>
SimpleUrlHandlerMapping:以Key-Value的方式来存储url和对应的handler
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/test" value-ref="test"/>
</map>
</property>
</bean>
RequestMappingHandlerMapping:是在类中使用RequestMapping注解来完成
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
3.5、<mvc:annotation-driven/>注解映射的支持,能实现自动注册Controller等
<mvc:annotation-driven/>
会自动注册DefaultAnnotationHandlerMapping与AnnotationMethoHandlerAdapter两个bean,
是spring MVC为@Controllers分发请求必须的提供了数据绑定支持,@NumberFormatannotation支持,
@DataTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
3.6、ViewResolver(视图解释类)
- 从一个逻辑视图映射到一个视图对象
- 可以排序
- JSP通常实现:
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
多视图控制器:当有JSP,FLT等多种页面生成展示方式时,spring默认使用的是”试图解析器链“。spring会在”视图解析器链“中顺序查找,直到找到对应的”视图解析器“,所以性能不优。
JSP视图解析器须写在前面,一旦调用JSP,就像浏览器发出数据了,spring没有机会再尝试下一个。
3.7、支持的视图
支持的视图模板技术
- InternalResourceView(JSP)
- JstlView(JSP+JSTL)
- VelocityView(Velocity)
- FreeMarkerView(FreeMarker)
- TilesView(Tiles)
- TilesJstlView(Tiles+JSTL)
支持渲染的视图
- Excel files
- PDF files
- XSLT results
- Jasper reports
四、Controller接口
- 负责处理请求
- 内部参数继承HttpServlet
- handleRequest(HttpServletRequest,HttpServletResponse);
- 返回一个ModelAndView对象
- 所有实现都是线程安全的
- 基本不用自己实现接口
4.1、Controller
@Controller
public class PersonController {
@RequestMapping(value="/toLogin",method=RequestMethod.GET)
public String toLogin(){
return "login";
}
@RequestMapping(value="/toAdd",method=RequestMethod.GET)
public String toAdd(){
return "add";
}
@RequestMapping(value="/add",method=RequestMethod.POST)
public String add(Person person){
return "redirect:queryAll";
}
@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(Person person){
if(10025==person.getPid()&&"123".equals(person.getPwd())){
return "redirect:queryAll";
}else{
return "login";
}
}
@RequestMapping(value="/queryAll",method=RequestMethod.GET)
public ModelAndView queryAll(){
ModelAndView mav=new ModelAndView("show");
List<Person> list=new ArrayList<Person>();
list.add(new Person(10025, "tom", "123"));
list.add(new Person(10026, "jakson", "123"));
list.add(new Person(10027, "nikly", "123"));
mav.addObject("list", list);
return mav;
}
index.jsp->toLogin->return “login” ->login->return “queryAll”->queryAll
- 可通过redirect/forward:url方式转到另一个Action进行连续的处理。通过redirect:url防止表单重复提交
- return “forward:/order/add”;
- return “redirect:queryAll”;
-queryAll方法中method=RequestMethod必须为GET
五、ModelAndView对象
- ModelAndView:方法处理完把值带到页面
- 封装了用来渲染页面的model和view
- Model用java.util.Map实现的
- 添加对象,可以不需要名字
- addObject(String,Object)用显式名字添加
- addObject(Object)用默认名添加
<!--例如:list把数据带到页面-->
@RequestMapping(value="/queryAll",method=RequestMethod.GET)
public ModelAndView queryAll(){
ModelAndView mav=new ModelAndView("show");
List<Person> list=new ArrayList<Person>();
list.add(new Person(10025, "tom", "123"));
list.add(new Person(10026, "jakson", "123"));
list.add(new Person(10027, "nikly", "123"));
mav.addObject("list", list);
return mav;
}
六、处理静态页面
详见3.2节内容,除此之外,还有:
<mvc:resources mapping="/**" location="/"/>
七、处理ajax请求
处理ajax,使用spring内置的json转换需要添加配置:
<mvc:annotation-driven/>
需要添加jar包:
jackson-core-asl-..*.jar
jackson-mapper-asl-..*.jar
@RequestMapping("/ajax")
@ResponseBody
public Object ajax(Person person){
System.out.println(person.getPid()+person.getPwd());
if(10025==person.getPid()&&"123".equals(person.getPwd())){
return "{\"flag\":true}";
}else{
return "{\"flag\":false}";
}
}
八、处理编码
修改web.xml,增加编码过滤器。(需要设置forceEncoding参数为true)
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<!-- encoding 是CharacterEncoding的一个属性-->
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<!--forceEncoding 是CharacterEncoding的一个属性-->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</filter>