一 处理器映射,配置文件
DispatcherServlet是spring mvc的核心,作为spring mvc的前端控制器, 必须在web.xml中声明如下:
<servlet> <servlet-name>spitter</servlet-name> //定义了servlet名字,将从于servlet相同名的xml中载入应用上下文,DispatcherServlet试图从spitter.xml中载入上下文 <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet>
<servlet-mapping> <servlet-name>spitter</servlet-name> <url-pattern>/</url-pattern> //DispatcherServlet需要处理所有请求 </servlet-mapping>
ContextLoaderListener 可以加在配置文件到servlet xml中,在web.xml中配置:
<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spitter-security.xml classpath:service-context.xml classpath:persistence-context.xml classpath:dataSource-context.xml </param-value> </context-param>
对于静态文件,可以使用
<?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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <mvc:resources mapping="/resources/**" //对于所有以resources开头的path,servlet会serve到应用程序根目录的resources下,一般放置图片,javascrpt等 location="/resources/" /> </beans>
spring有5种方法分配请求到controller
1 BeanNameUrlHandlerMapping 扫描bean,将以”/”开头的bean的名称或别名(alias)注册为可以处理的url
2 ControllerBeanNameHandlerMapping 和第一个类似,但是beanname不要求和url规定一样
3 ControllerClassNameHandlerMapping controller class name和url关系
4 DefaultAnnotationHandlerMapping 注解 <mvc:annotation-driven/>
这个标签注册了Spring MVC分发请求到控制器所必须的DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例
5 SimpleUrlHandlerMapping 在spring上下文种定义controller和url关系
二 控制器
package com.habuma.spitter.mvc; import javax.inject.Inject; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.habuma.spitter.service.SpitterService; @Controller //定义一个controller,在servlet中配置<context:component-scan base-package="com.habuma.spitter.mvc" />,controller自动配置成bean public class HomeController { public static final int DEFAULT_SPITTLES_PER_PAGE = 25; private SpitterService spitterService; @Inject public HomeController(SpitterService spitterService) { //注入service this.spitterService = spitterService; } @RequestMapping({"/","/home"}) //处理请求 public String showHomePage(Map<String, Object> model) {//model是controller和view传送数据 model.put("spittles", spitterService.getRecentSpittles( DEFAULT_SPITTLES_PER_PAGE));  return "home"; //返回view } }
处理input, url:http://localhost:8080/spitter/spitters/spittles?spitter=habuma
@Controller @RequestMapping("/spitter") public class SpitterController { private final SpitterService spitterService; @Inject public SpitterController(SpitterService spitterService) { this.spitterService = spitterService; } @RequestMapping(value="/spittles", method=GET)//Handle GET requests for /spitter/spittles public String listSpittlesForSpitter(  @RequestParam("spitter") String username, Model model) {//第二个参数和前面例子的map类似,map的put方法和model的addattribute方法类似 Spitter spitter = spitterService.getSpitter(username); model.addAttribute(spitter); model.addAttribute(spitterService.getSpittlesForSpitter(username)); return "spittles/list"; } }
When adding a Spitter object to the model, addAttribute() gives it the name spitter, a name it arrives at by applying JavaBeans property naming rules to the object’s class name. When adding a List of Spittles, it tacks List to the end the mem- ber type of the List, naming the attribute spittleList.
jsp中这样调用
<h2>Spittles for ${spitter.username}</h2> <table cellspacing="15"> <c:forEach items="${spittleList}" var="spittle">
如何测试一个controller
package com.habuma.spitter.mvc; import static com.habuma.spitter.mvc.HomeController.*; import static java.util.Arrays.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.List; import org.junit.Test; import com.habuma.spitter.domain.Spittle; import com.habuma.spitter.service.SpitterService; public class HomeControllerTest { @Test public void shouldDisplayRecentSpittles() { List<Spittle> expectedSpittles = asList(new Spittle(), new Spittle(), new Spittle()); SpitterService spitterService = mock(SpitterService.class); Mock SpitterService when(spitterService.getRecentSpittles(DEFAULT_SPITTLES_PER_PAGE)). thenReturn(expectedSpittles); HomeController controller = new HomeController(spitterService); //Create controller HashMap<String, Object> model = new HashMap<String, Object>(); String viewName = controller.showHomePage(model); //Call handler method assertEquals("home", viewName); assertSame(expectedSpittles, model.get("spittles")); verify(spitterService).getRecentSpittles(DEFAULT_SPITTLES_PER_PAGE); } }
三 视图解析器
具体view可由jsp或者velocity写,视图解析器将逻辑viewname转换为实际的viewpath
BeanNameViewResolver view注册成bean,id和logic view name一样
ContentNegotiatingViewResolver
FreeMarkerViewResolver
InternalResourceViewResolver
JasperReportsViewResolver
ResourceBundleViewResolver
TilesViewResolver
UrlBasedViewResolver
VelocityLayoutViewResolver
VelocityViewResolver
XmlViewResolver
XsltViewResolver
InternalResourceViewResolver
<bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean>
TilesViewResolver
用来组合成一个最终表示用页面用的,这样的话,便于对页面的各个机能的变更及维护。
//in spitter-servlet.xml: <bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver"/>//定义TilesViewResolver根据视图逻辑名找到定义对应的view <bean class= "org.springframework.web.servlet.view.tiles2.TilesConfigurer"> <property name="definitions">//tiles定义的文件 <list> <value>/WEB-INF/viewsviews.xml</value> </list> </property> </bean> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd"> <tiles-definitions>//tiles定义 <definition name="template" template="/WEB-INF/views/main_template.jsp"> <put-attribute name="top" value="/WEB-INF/views/tiles/spittleForm.jsp" /> <put-attribute name="side" value="/WEB-INF/views/tiles/signinsignup.jsp" /> //Define common layout </definition> <definition name="home" extends="template"> //Define home tile  <put-attribute name="content" value="/WEB-INF/views/home.jsp" /> </definition> </tiles-definitions>
表单请求
new
@RequestMapping(method=RequestMethod.GET, params="new") //只能处理get请求 public String createSpitterProfile(Model model) { model.addAttribute(new Spitter()); return "spitters/edit"; }
<definition name="spitters/edit" extends="template">//xml中 <put-attribute name="content" value="/WEB-INF/views/spitters/edit.jsp" /> </definition>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <div> <h2>Create a free Spitter account</h2> <sf:form method="POST" modelAttribute="spitter"> <fieldset> <table cellspacing="0"> <tr>  <th><label for="user_full_name">Full name:</label></th> <td><sf:input path="fullName" size="15" id="user_full_name"/></td> </tr> <tr> <th><label for="user_screen_name">Username:</label></th> <td><sf:input path="username" size="15" maxlength="15" id="user_screen_name"/> <small id="username_msg">No spaces, please.</small> </td> </tr> <tr> <th><label for="user_password">Password:</label></th> <td><sf:password path="password" size="30" showPassword="true" id="user_password"/> <small>6 characters or more (be tricky!)</small> </td> </tr> <tr> <th><label for="user_email">Email Address:</label></th> <td><sf:input path="email" size="30" id="user_email"/> <small>In case you forget something</small> </td> </tr> <tr>  <th></th> <td> <sf:checkbox path="updateByEmail" id="user_send_email_newsletter"/> <label for="user_send_email_newsletter" >Send me email updates!</label> </td> </tr> </table> </fieldset> </sf:form> </div>
post
@RequestMapping(method=RequestMethod.POST) public String addSpitterFromForm(@Valid Spitter spitter,BindingResult bindingResult) {//spitter必须先验证 if(bindingResult.hasErrors()) {//判断是否由error return "spitters/edit";//Check for errors } spitterService.saveSpitter(spitter);//Save Spitter //Redirect after POST  return "redirect:/spitters/" + spitter.getUsername(); } @RequestMapping(value="/{username}", method=RequestMethod.GET) public String showSpitterProfile(@PathVariable String username,//路径名称为参数 Model model) { model.addAttribute(spitterService.getSpitter(username)); return "spitters/view"; }
验证@valid
http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html
@Pattern(regexp="^[a-zA-Z0-9]+$", message="Username must be alphanumeric with no spaces") private String username; @Size(min=6, max=20, message="The password must be at least 6 characters long.") private String password; //spitter类中
BindingResult’s getFieldError() 可显示error,也可使用标签
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <div> <h2>Create a free Spitter account</h2> <sf:form method="POST" modelAttribute="spitter" enctype="multipart/form-data"> <fieldset> <table cellspacing="0"> <tr> <th><sf:label path="fullName">Full name:</sf:label></th> <td><sf:input path="fullName" size="15" /><br/> <sf:errors path="fullName" cssClass="error" /> </td> </tr> ... </table> </fieldset> </sf:form> </div>
<sf:errors path="*" cssClass="error" />可显示所有的error在同一个地方
资料:
http://blog.csdn.net/walkerjong/article/details/7946109
handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
A、处理requet uri 部分(这里指uri template中variable,不含queryString部分)的注解: @PathVariable;
B、处理request header部分的注解: @RequestHeader, @CookieValue;
C、处理request body部分的注解:@RequestParam, @RequestBody;
D、处理attribute类型是注解: @SessionAttributes, @ModelAttribute;