package com.atguigu.my.controller; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.atguigu.my.bean.Employee; import com.atguigu.my.dao.EmployeeDao; @Controller public class JsonController { @Autowired private EmployeeDao employeeDao; @RequestMapping(value = "/testJson") @ResponseBody public Collection<Employee> getAll() { Collection<Employee> emps = employeeDao.getAll(); ; return emps; } }
只是寫一個<a href = "testJson">測試json</a>java
而後再springmvc.xml中開啓註解驅動<mvc:annotation-driven/>web
而後須要印如jackson的三個jar包,jackson是阿里巴巴產品,可以自動將java對象轉爲json對象spring
<?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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 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-4.0.xsd"> <context:component-scan base-package="com.atguigu"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"></property> <property name="suffix" value=".jsp"></property> </bean> <mvc:default-servlet-handler/> <mvc:annotation-driven /> <!-- 處理文件,將客戶端上傳的File文件,處理爲MultipartFile 注意:文件解析器的bean中id必須設置爲multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 設置文件解析的編碼,注意:必定要和頁面的pageEncoding保持一致 --> <property name="defaultEncoding" value="UTF-8"></property> <!-- 設置最大上傳文件大小 --> <property name="maxUploadSize" value="88888888"></property> </bean> <mvc:interceptors> <!-- 默認攔截全部請求 --> <bean class="com.atguigu.interceptor.FirstInterceptor"></bean> <bean class="com.atguigu.interceptor.SecondInterceptor"></bean> <!-- 此方式要求攔截器類上必須加註解@Component --> <!-- <ref bean="firstInterceptor"/> --> <!-- 設置自定義攔截方式 --> <!-- <mvc:interceptor> <bean></bean> <mvc:mapping path=""/> <mvc:exclude-mapping path=""/> </mvc:interceptor> --> </mvc:interceptors> </beans>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SpringMVC04</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>CharacterEncodingFilter</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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- The front controller of this Spring Web application, responsible for handling all application requests --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- Map all requests to the DispatcherServlet for handling --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
package com.atguigu.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class FirstInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("First:preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("First:postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("First:afterCompletion"); } }
package com.atguigu.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class SecondInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Second:preHandle"); //統計請求耗時 long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Second:postHandle"); long startTime = (Long)request.getAttribute("startTime"); long endTime = System.currentTimeMillis(); long executeTime = endTime - startTime; //modified the exisitng modelAndView modelAndView.addObject("executeTime",executeTime); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("Second:afterCompletion"); } }
package com.atguigu.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestInterceptorController { /** * 當有多個攔截器時, * preHandle:按照攔截器數組的正向順序執行 * postHandle:按照攔截器數組的反向順序執行 * afterCompletion:按照攔截器數組的反向順序執行 * * 當多個攔截器的preHandle有不一樣的值時 * 第一個返回false,第二個返回false:只有第一個preHandle會執行 * 第一個返回true,第二個返回false:兩個(所有)攔截器的preHandle都會執行 * 可是(所有)postHandle都不會執行,而afterCompletion只有第一個(返回false的攔截器以前的全部afterCompletion)會執行 * 第一個返回false,第二個返回true:只有第一個的preHandle會執行 */ @RequestMapping("/testInterceptor") public String testInterceptor() { return "success"; } }
Spring的Interceptor(攔截器)與Servlet的Filter有類似之處,好比兩者都是AOP編程思想的體現,都能實現權限檢查、日誌記錄等。不一樣的是:編程
Filter | Interceptor | Summary |
---|---|---|
Filter 接口定義在 javax.servlet 包中 | 接口 HandlerInterceptor 定義在org.springframework.web.servlet 包中 | |
Filter 定義在 web.xml 中 | ||
Filter在只在 Servlet 先後起做用。Filters 一般將 請求和響應(request/response) 當作黑盒子,Filter 一般不考慮servlet 的實現。 | 攔截器可以深刻到方法先後、異常拋出先後等,所以攔截器的使用具備更大的彈性。容許用戶介入(hook into)請求的生命週期,在請求過程當中獲取信息,Interceptor 一般和請求更加耦合。 | 在Spring構架的程序中,要優先使用攔截器。幾乎全部 Filter 可以作的事情, interceptor 都可以輕鬆的實現 |
Filter 是 Servlet 規範規定的。 | 而攔截器既能夠用於Web程序,也能夠用於Application、Swing程序中。 | 使用範圍不一樣 |
Filter 是在 Servlet 規範中定義的,是 Servlet 容器支持的。 | 而攔截器是在 Spring容器內的,是Spring框架支持的。 | 規範不一樣 |
Filter 不可以使用 Spring 容器資源 | 攔截器是一個Spring的組件,歸Spring管理,配置在Spring文件中,所以能使用Spring裏的任何資源、對象,例如 Service對象、數據源、事務管理等,經過IoC注入到攔截器便可 | Spring 中使用 interceptor 更容易 |
Filter 是被 Server(like Tomcat) 調用 | Interceptor 是被 Spring 調用 | 所以 Filter 老是優先於 Interceptor 執行 |
interceptor 的執行順序大體爲:json
首先咱們看下攔截器的如何被調用的。數組
Web請求被DispatcherServlet截獲後,會調用DispatcherServlet的doDispatcher方法。spring-mvc
很明顯地看到,在HandlerAdapter處理以後,以及處理完成以後會調用HandlerExecutionChain的方法。session
HandlerExecutionChain的applyPreHandle、applyPostHandle、triggerAfterCompletion方法以下:mvc
很明顯,就是調用內部實現HandlerInterceptor該接口集合的各個對應方法。app
下面咱們看下HandlerExecutionChain的構造過程。
HandlerExecutionChain是從HandlerMapping接口的getHandler方法獲取的。
HandlerMapping的基礎抽象類AbstractHandlerMapping中:
咱們看到,HandlerExecutionChain的攔截器是從AbstractHandlerMapping中的adaptedInterceptors和mappedInterceptors屬性中獲取的。
package com.atguigu.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import javax.servlet.http.HttpSession; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; @Controller public class TestUploadAndDownController { @RequestMapping("/down") public ResponseEntity<byte[]> down(HttpSession session) throws IOException{ //獲取下載文件的路徑 String realPath = session.getServletContext().getRealPath("img"); String finalPath = realPath + File.separator + "2.jpg"; InputStream is = new FileInputStream(finalPath); //available():獲取輸入流所讀取的文件的最大字節數 byte[] b = new byte[is.available()]; is.read(b); //設置請求頭 HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename=zzz.jpg"); //設置響應狀態 HttpStatus statusCode = HttpStatus.OK; ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(b, headers, statusCode); return entity; } @RequestMapping(value="/up", method=RequestMethod.POST) public String up(String desc, MultipartFile uploadFile, HttpSession session) throws IOException { //獲取上傳文件的名稱 String fileName = uploadFile.getOriginalFilename(); String finalFileName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf(".")); String path = session.getServletContext().getRealPath("photo") + File.separator + finalFileName; File file = new File(path); uploadFile.transferTo(file); return "success"; } @RequestMapping(value="/up_old", method=RequestMethod.POST) public String up_old(String desc, MultipartFile uploadFile, HttpSession session) throws IOException { //獲取上傳文件的名稱 String fileName = uploadFile.getOriginalFilename(); String path = session.getServletContext().getRealPath("photo") + File.separator + fileName; //獲取輸入流 InputStream is = uploadFile.getInputStream(); //獲取輸出流 File file = new File(path); OutputStream os = new FileOutputStream(file); /*int i = 0; while((i = is.read()) != -1) { os.write(i); }*/ /*int i = 0; byte[] b = new byte[1024]; while((i = is.read(b)) != -1) { os.write(b, 0, i); }*/ os.close(); is.close(); return "success"; } }
這個和操做系統有關係,最好加一個/, 血淚史啊