本節主要講解SpringMVC. :) html
=============================== 前端
瀏覽器請求->DispatcherServlet->MVC控制器(數據交互,產生信息Model)+View名稱 java
->DispatcherServlet->查詢視圖解析器->視圖渲染。 web
SpringMVC的核心是DispatchServlet.它充當前端控制器。 spring
與其它servlet同樣,DispatchServlet必須在web應用程序的web.xml文件中進行配置。 瀏覽器
因此在應用程序使用SpringMVC的第一件事就是將下面的<servlet>放入到web.xml中。 spring-mvc
<servlet>
<servlet-name>spitter</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> mvc
因爲這裏的名字是spitter,因此DispatcherServlet會嘗試從一個WEB-INF/spitter-servlet.xml文件中加載上下文 app
========== 框架
接下來應該聲明URL映射,好比
*.html代表響應是html格式的
/*將處理全部的請求
/app不解釋。
推薦用這種模式
<servlet-mapping>
<servlet-name>spitter</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
下面是建立spitter-servlet.xml文件,內容
<mvc:resource>用於處理靜態資源請求
<?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/**" location="/resources/" />
<mvc:annotaion-driven />
<context:component-scan base-package="com.habuma.spitter.mvc" />
</beans>
======================================================================
其它的, DispatcherServlet須要諮詢一個或者多個處理器映射來明確的將請求分發給某個控制器。
Spring自帶了多個處理器映射實現供咱們選擇:
1 BeanNameUrlHandlerMapping:根據控制器bean的名字將控制器映射到URL
2 ControllerBeanNameHandlerMapping: 與BeanNameUrlHandlerMapping相似,根據控制器bean的名字將控制器映射到URL。
使用該處理器映射實現,bean的名字不須要遵循URL的約定。
3 ControllerClassNameHandlerMapping: 經過使用控制器的類名做爲URL基礎將控制器映射到URL
4 DefaultAnnotationHandlerMapping: 將請求映射給使用@Request-Mapping註解的控制器和控制器方法
5 SimpleUrlHandlerMapping: 使用定義在spring應用上下文的屬性集合將控制器映射到URL.
使用如上這些處理器映射一般只須要在spring中配置一個bean,若是沒有找處處理器映射bean
DispatcherServlet將建立使用BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping.
下面看一個例子
package com.habuma.spitter.mvc;
import java.util.Map;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/*
* @Controller是@Component註解的一種具體化,<context:component-scan>將查找使用@Component註解的類
* 並註冊爲Bean.因此須要在spitter-servlet.xml中配置
* <context:component-scan base-package="com.habuma.spitter.mvc" />
*/
@Controller
public class HomeController {
public static final int DEFAULT_SPITTLES_PER_PAGE = 25;
private SpitterService spitterService;
@Inject
public HomeController(SpitterService spitterService) {
this.spitterService = spitterService;
}
@RequestMapping({ "/", "/home" })
public String showHomePage(Map<String, Object> model) {
model.put("spittles",
spitterService.getRecentSpittles(DEFAULT_SPITTLES_PER_PAGE));
return "home";
}
}
剩下的任務是視圖渲染jsp,Velocity或者FreeMarker.
DispatcherServlet會查找一個視圖解析器將"home"轉化成實際視圖。
實際上,視圖解析器的工做就是將名字與org.springframework.web.servlet.View的實現相匹配。
視圖解析器 描述
BeanNameViewResolver 查找<bean>ID與邏輯視圖名稱相同View的實現。
ContentNegotiatingViewResolver 委託給一個或者多個視圖解析器,而選擇哪個取決於請求的內容類型
FreeMakerViewResolver 查找一個基於FreeMaker的模板,它的路徑根據加完前綴和後綴的邏輯視圖名稱來肯定
InternalResourceViewResolver 在web應用程序的WAR文件中查找視圖模板,視圖模板的路徑根據加完前綴和後綴的邏輯視圖名稱來肯定 ,好比/WEB-INF/views/home.jsp
JasperReportsViewResolver 根據加完前綴和後綴的邏輯視圖名稱來查找一個JasperReport報表文件
ResourceBundleViewResolver 根據屬性文件來查找view實現
TilesViewResolver 查找經過Tiles模板定義的視圖,模板的名字與邏輯視圖名稱相同
UrlBasedViewResolver 這是一些其餘視圖解析器的基類,能夠單獨使用,可是沒有它的子類強大,例如:UrlBasedViewResolver不能基於當前的語言環境來解析視圖。
VelocityLayoutViewResolver 它是 VelocityViewResolver的子類,它支持經過spring的VelocityLayoutView來進行頁面的組合
VelocityViewResolver 解析基於Velocity的視圖,Velocity模板的路徑根據加完前綴和後綴的邏輯視圖名來肯定。
XmlViewResolver 查找在XML文件(/WEB-INF/views.xml)中聲明的view實現,這個視圖解析器與BeanNameViewResolver很相似,可是在這裏
視圖<bean>的聲明與應用程序spring上下文的其它<bean>是分開的。
XsltViewResolver 解析基於XSLT的視圖,XSLT樣式表的路徑根據加完前綴和後綴的邏輯視圖名稱來肯定。
因此對於spitter-servlet.xml中能夠這麼配置
針對:InternalResourceViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--若是jsp使用了一些JSTL標籤-->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp" />
</bean>
==========================
在另一個地方也能夠加載配置文件,在web.xml中
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
爲了給ContextLoaderListener 指定一個或者多個spring配置文件,要在servlet上下文中配置
<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>
一個例子:
package com.habuma.spitter.mvc;
import java.util.Map;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/*
* @Controller是@Component註解的一種具體化,<context:component-scan>將查找使用@Component註解的類
* 並註冊爲Bean.因此須要在spitter-servlet.xml中配置
* <context:component-scan base-package="com.habuma.spitter.mvc" />
*/
@Controller
public class HomeController {
public static final int DEFAULT_SPITTLES_PER_PAGE = 25;
private SpitterService spitterService;
@Inject
public HomeController(SpitterService spitterService) {
this.spitterService = spitterService;
}
@RequestMapping({ "/", "/home" })
public String showHomePage(Map<String, Object> model) {
model.put("spittles",
spitterService.getRecentSpittles(DEFAULT_SPITTLES_PER_PAGE));
return "home";
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spitter</servlet-name>
<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>
</servlet-mapping>
</web-app>
===spitter-servlet.xml
<?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/**" location="/resources/" />
<context:component-scan base-package="com.habuma.spitter.mvc" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp" />
</bean>
</beans>
package com.habuma.spitter.mvc;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/spitter")
/*
* 上面是根URL路徑
*/
public class SpitterController {
private SpitterService spitterService=null;
@Inject
public SpitterController(SpitterService spitterService) {
this.spitterService = spitterService;
}
@RequestMapping(value="/spittles",method=RequestMethod.GET)
public String listSpittlesForSpitter(
@RequestParam("spitter") String username,Model model){
///獲取數據
model.addAttribute(data);
return "xxxxxx";
}
}
----------------其它
@RequestMapping(method=RequestMethod.GET,params="new")
public String createSplitterProfile(Model model){
model.addAllAttributes(xxx);
return "viewOfYourName";
}對應着類級別的路徑,包含new參數。
@RequestMapping(method=RequestMethod.POST)
public String addSpitterFromForm(@Valid Spitter spitter,BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "xxx";
}
//保存數據的邏輯
return "redirect:/spiiters/xxx";//重定向
}
@RequestMapping(value="/{username}",method=RequestMethod.GET)
public String showSpitterProfile(@PathVariable String username,Model model){
...
return "viewName";
} 好比/username/habuma.
其實仍是使用play框架更方便!
Spring這玩意還真是折騰啊!
---關於校驗
@Size(min=3,max=20,message="Username must be between 3 and 20 characters long.")
@Pattern(regexp="^[a-zA-Z0-9]+$",message="username must be alphanumeric with no space")
private String username;