2019-06-14
Spring 框架提供了構(gòu)建 Web 應(yīng)用程序的全功能 MVC 模塊,可以取代Servlet,構(gòu)建輕量級框架。
SpringMVC基本配置
編寫Spring控制器
@Controller
public class LoginController{
//給處理方法添加RequestMapping注解
//對應(yīng)前端請求地址http://localhost:8080/TestApp/login.do
@RequestMapping("/login.do")
public String login(Users users) {
if ("admin".equals(users.getUsername())
&& "123456".equals(users.getPassword())) {
return "index";
} else {
return "login";
}
}
}
可以使用@RequestMapping添加類級別注解
@Controller
@RequestMapping ("/UsersController")
public class UsersController {
@RequestMapping ("/login.do")
public String login() {
return "login";
}
@RequestMapping ("/register.do")
public String register () {
return "register";
}
}
//對應(yīng)地址http://localhost:8080/TestApp/UsersController/login.do
SpringMVC默認的響應(yīng)類型為服務(wù)器轉(zhuǎn)發(fā),如果不想通過視圖解析器進行響應(yīng),可以使用如下語句:
return "redirect:/xxx.jsp" //重定向
return "forward:/xxx.jsp" //服務(wù)器轉(zhuǎn)發(fā)
編寫SpringMVC核心配置文件 spring-mvc.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<!--啟用spring mvc注解 -->
<mvc:annotation-driven />
<!--設(shè)置使用注解的類所在的包路徑 -->
<context:component-scan base-package="com.jevon.controller" />
<!--視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--prefix和suffix:配置視圖頁面的前綴和后綴(前綴[邏輯視圖名]后綴 -->
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
<!--JstlView視圖類 -->
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType">
<value>text/html;charset=utf-8</value>
</property>
</bean>
<!-- 靜態(tài)資源不經(jīng)過controller -->
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/js/**" location="/js/" />
</beans>
配置web.xml,啟動Spring
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--指定配置文件路徑 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--通過ContextLoaderListener啟用spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--請求監(jiān)聽器 -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!--核心控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!--請求編碼過濾器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--啟動頁 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>login.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
請求處理方法的參數(shù)
如果需要在請求處理方法中使用Servlet API類型,可以將這些類型作為請求參數(shù)來接收處理。
可以編寫控制器父類攔截Servlet API進行封裝。
public class GenericController {
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession session;
protected ServletContext application;
//被@ModelAttribute注釋的方法會在此controller每個方法執(zhí)行前被執(zhí)行, 可以用來攔截請求、控制登錄權(quán)限等
@ModelAttribute
public void setServletApi(HttpServletRequest request,HttpServletResponse response) {
this.request = request;
this.response = response;
this.session = request.getSession();
this.application = request.getServletContext();
}
}
參數(shù)類型自動轉(zhuǎn)換
在SpringMVC框架中,對于常用的數(shù)據(jù)類型,開發(fā)者無須手動進行類型轉(zhuǎn)換,SpringMVC框架有許多內(nèi)置的類型轉(zhuǎn)換器用于完成常用的類型轉(zhuǎn)換。
ModelAndView返回值
? SpringMVC提供了org.springframework.web.servlet.ModelAndView類封裝邏輯視圖及返回值。該類可以添加Map結(jié)構(gòu)數(shù)據(jù)。
new ModelAndView(邏輯視圖);
new ModelAndView(邏輯視圖,鍵,值);
ModelAndView mv = new ModelAndView();
mv.setViewName(邏輯視圖);
mv.addObject(鍵,值);
SpringMVC的工作流程

- 客戶端請求被DispatcherServlet(前端控制器)接收,然后根據(jù)url映射到業(yè)務(wù)控制器,然后調(diào)用業(yè)務(wù)控制器的方法做業(yè)務(wù)邏輯處理。
- 業(yè)務(wù)控制器返回ModelAndView對象(邏輯視圖)給DispatcherServlet。
- DispatcherServlet將獲取的邏輯視圖傳給ViewResolver視圖解析器,將邏輯視圖解析成物理視圖。
- ViewResolver將物理視圖返回給DispatcherServlet。
- DispatcherServlet將渲染后的物理視圖響應(yīng)給客戶端。
Ajax響應(yīng)
與Servlet用法基本相同,通過上面的controller父類獲取到response對象,拿到輸出流寫入即可
Spring4的控制器可以使用response對象做出ajax響應(yīng),并利用@ResponseBody注解自動將數(shù)據(jù)生成json響應(yīng)給瀏覽器。
@RequestMapping("/UsersController_findById.do")
public @ResponseBody Users findById(String id) {
return this.usersService.findById(id);
}
@RequestMapping("/UsersController_findAll.do")
public @ResponseBody List<Users> findAll() {
List<Users> lists = this.usersService.findAll();
return lists;
}
@RequestMapping("/UsersController_findAllByMap.do")
public @ResponseBody List<Map<String, String>> findAllByMap () {
List<Map<String, String>> lists = this.usersService.findAll();
return results;
}
文件上傳
SpringMVC框架的文件上傳基于commons-fileupload組件實現(xiàn),只不過SpringMVC框架在原有文件上傳組件上做了進一步封裝,簡化了文件上傳的代碼實現(xiàn)。
上傳表單
<form action="FileController_upload.do" method="post" enctype="multipart/form-data">
<p>
請選擇照片:<input type="file" name="photo" />
</p>
<input type="submit" value="上傳" />
</form>
控制器
//處理文件上傳 如果上傳多個文件,
//可以設(shè)定MultipartFile數(shù)組或List集合參數(shù) List<MultipartFile> photo
@RequestMapping("/FileController_upload.do")
public String upload(MultipartFile photo) throws Exception {
if (photo.isEmpty()) {
System.out.println("文件未上傳");
return "error";
} else {
System.out.println("文件名: " + file.getOriginalFilename());
System.out.println("文件類型: " + file.getContentType());
System.out.println("文件大小: " + file.getSize());
System.out.println("========================================");
String fileName = photo.getOriginalFilename();
String ext = fileName.substring(fileName.lastIndexOf("."),
fileName.length());// 獲得上傳文件的擴展名
String newFileName = new SimpleDateFormat("yyyyMMddhhmmssSSS")
.format(new Date())+ (10000 + new Random().nextInt(90000)) + ext;
File destFile = new File(this.application
.getRealPath("upload"), newFileName); // 創(chuàng)建目標(biāo)文件
photo.transferTo(destFile);// 復(fù)制文件
return "success";
}
}
spring-mvc.xml文件上傳配置
<!--文件上傳處理器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!-- 指定所上傳文件的總大小不能超過512K。
注意maxUploadSize屬性的限制不是針對單個文件,而是所有文件的容量之和
-->
<property name="maxUploadSize" value="512000"/>
</bean>
<!--文件上傳異常處理器 -->
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- 拋出異常時,自動跳轉(zhuǎn)到指定頁面 -->
<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">
error
</prop>
</props>
</property>
</bean>
MultipartFile API說明
| 返回值 | 方法名 | 說明 |
|---|---|---|
| byte[] | getBytes() | 以字節(jié)數(shù)組類型返回文件內(nèi)容 |
| String | getContentType() | 獲取文件類型 |
| InputStream | getInputStream() | 獲取穩(wěn)健的輸入流 |
| String | getName() | 返回參數(shù)名稱多部分的形式 |
| String | getOriginalFilename | 返回文件名 |
| long | getSize() | 返回文件大?。ㄗ止?jié)) |
| boolean | isEmpty() | 判斷是否為空 |
| void | transferTo() | 復(fù)制文件到指定文件 |
文件下載
@RequestMapping("/FileController_download.do")
public void downLoad(String id) throws Exception {
String path = this.application.getRealPath("upload") + "\\2017090102581803133040.jpg";
File file = new File(path);
this.response.setContentType("application/x-msdownload;charset=utf-8");
this.response.setHeader("Content-disposition","attachment; filename="
+ new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
this.response.setHeader("Content-Length", String.valueOf(file.length()));
InputStream input = new FileInputStream(file);
byte data[] = new byte[(int) file.length()];
input.read(data);
input.close();
OutputStream out = this.response.getOutputStream();
out.write(data);
out.close();
}
springmvc異常統(tǒng)一處理
在J2EE項目的開發(fā)中,不管是對底層的數(shù)據(jù)庫操作過程,還是業(yè)務(wù)層的處理過程,還是控制層的處理過程,都不可避免會遇到各種異常需要處理。如果每個過程都單獨手動用try-catch處理,則系統(tǒng)的代碼耦合度高,工作量大且不好統(tǒng)一,維護的工作量也很大。 Spring MVC提供了統(tǒng)一處理異常的解決方案。
Spring MVC處理異常有3種方式:
- 使用Spring MVC提供的異常處理器SimpleMappingExceptionResolver;
- 實現(xiàn)Spring的異常處理接口HandlerExceptionResolver 自定義異常處理器;
- 使用@ExceptionHandler注解實現(xiàn)異常處理;
修改spring-mvc.mxl
<!-- 異常處理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定義默認的異常處理頁面 -->
<property name="defaultErrorView" value="error"></property>
<!-- 定義異常處理頁面用來獲取異常信息的變量名,默認名為exception -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 定義需要特殊處理的異常,用類名或完全路徑名作為key,異常處理頁名作為值 -->
<property name="exceptionMappings">
<props>
<prop key="com.exception.MyException">error_myexception</prop>
<!-- 這里還可以繼續(xù)擴展對不同異常類型的處理 -->
</props>
</property>
</bean>