實現文件上傳,須要藉助如下兩個第三方 jar 包對上傳的二進制文件進行解析:css
form表單的 enctype 取值必須爲:multipart/form-data(默認爲:application/x-www-form-urlencoded);enctype爲表單請求正文的類型;method 屬性必須取值爲 post 方式;提供一個文件選擇域: <input type="file"/>
;html
<form action="fileUpload/fileUploadOld" method="post" enctype="multipart/form-data"> <input type="file" name="fileUpload"/><br/> <input type="submit" value="上傳"/> </form>
@RequestMapping(value = "/fileUploadOld", method = RequestMethod.POST) public String fileUploadOld(HttpServletRequest request) throws Exception { //獲取上傳文件存放位置:絕對路徑 String path = request.getServletContext().getRealPath("/uploads/"); //判斷文件是否存在 File file = new File(path); if (!file.exists()) { file.mkdirs();//不存在則建立文件 } //解析request對象,獲取文件上傳項 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request); //遍歷 for (FileItem item : items) { //判斷item對象是否表單項 if (item.isFormField()) { //true,代表是普通表單 } else { //false,代表是上傳文件項 //獲取上傳文件名稱 String fileName = item.getName(); //把文件名稱設置爲惟一值 String uuid = UUID.randomUUID().toString().replace("-", ""); fileName = uuid + "_" + fileName; request.setAttribute("fileName", fileName); //完成文件上傳 item.write(new File(path, fileName)); //刪除臨時文件 item.delete(); } } return "succeed"; }
原理:文件上傳請求發送到前端控制器時,會轉給文件解析器並返回文件上傳項,而後前端控制器將文件上傳項發送到控制器方法,最後完成上傳操做;前端
注意:java
代碼實現web
@RequestMapping(value = "/fileUploadMvc", method = RequestMethod.POST) public String fileUploadMvc(HttpServletRequest request, MultipartFile fileUpload) { //獲取上傳文件存放位置:絕對路徑 String path = request.getServletContext().getRealPath("/uploads/"); //判斷文件是否存在 File file = new File(path); if (!file.exists()) { file.mkdirs();//不存在則建立文件 } //獲取上傳文件名 String filename = fileUpload.getOriginalFilename(); //把文件名稱設置爲惟一值 String uuid = UUID.randomUUID().toString().replace("-", ""); filename = uuid + "_" + filename; //上傳文件 try { fileUpload.transferTo(new File(path, filename)); } catch (IOException e) { e.printStackTrace(); } return "succeed"; }
Spring MVC配置文件中配置 CommonsMultipartResolver
spring
<!--配置文件解析器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--設置最大上傳文件的大小:10M--> <property name="maxUploadSize" value="10485760"/> </bean>
分服務器的目的:讓服務器各司其職,從而提升項目的運行效率;在實際開發中,會有不少處理不一樣功能的服務器。例如:數據庫
部署多臺服務器的操做apache
部署兩臺服務器,並建立一個用於存放圖片的 Web 工程;瀏覽器
配置存放圖片的服務器能夠支持寫入操做;spring-mvc
<servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>readonly</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
實現跨服務器文件上傳
@RequestMapping(value = "/fileUploadMultiServer", method = RequestMethod.POST) public String fileUploadMultiServer(MultipartFile fileUpload) { //定義上傳文件存放服務器位置:絕對路徑 String path = "服務器域名/URI"; //聲明上傳文件項 //獲取上傳文件名稱 String filename = fileUpload.getOriginalFilename(); //把文件名稱設置爲惟一值 String uuid = UUID.randomUUID().toString().replace("-", ""); filename = uuid + "_" + filename; /* 完成文件上傳,跨服務器上傳 (1)建立客戶端對象; (2)和FileServer服務器進行鏈接; (3)上傳文件 */ //建立 sun 公司提供的 jersey 包中的 Client 對象 Client client= Client.create(); //指定上傳文件的地址,該地址是 web 路徑 WebResource webResource = client.resource(path + filename); try { webResource.put(fileUpload.getBytes()); } catch (IOException e) { e.printStackTrace(); } return "succeed"; }
Spring MVC配置文件中配置 CommonsMultipartResolver
<!--配置文件解析器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--設置最大上傳文件的大小:10M--> <property name="maxUploadSize" value="10485760"/> </bean>
注意
系統中異常包括兩類:預期異常和運行時異常 RuntimeException,前者經過捕獲異常從而獲取異常信息,後者主要經過規範代碼開發、測試手段減小運行時異常的發生;
Spring MVC項目中的 dao、service、controller 出現的異常都經過 throws Exception 向上拋出,最後,要麼由瀏覽器輸出異常信息,要麼在前端控制器中經過異常解析器進行異常處理;
自定義異常類;
package spitter.exception; /** * 自定義異常類 */ public class SystemException extends Exception{ //存儲異常信息 private String massage; public SystemException(String massage) { this.massage = massage; } public String getMassage() { return massage; } public void setMassage(String massage) { this.massage = massage; } }
定義異常處理器:該類實現HandlerExceptionResolver,並重寫resolveException方法;
package spitter.exception; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 自定義異常處理器 */ public class SystemExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException( HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception ex ) { //獲取異常對象 SystemException se=null; if (e instanceof SystemException){ se= (SystemException) ex; }else { se=new SystemException("系統正在維護..."); } ModelAndView mav=new ModelAndView(); mav.addObject("error",se.getMassage()); mav.setViewName("error"); return mav; } }
Spring MVC配置文件中配置異常處理器;
<!--裝配異常處理器--> <bean id="systemExceptionResolver" class="spitter.exception.SystemExceptionResolver"/>
Spring MVC 的處理器攔截器相似於 Servlet 開發中的過濾器 Filter,用於對處理器進行預處理和後處理。 用戶能夠本身定義一些攔截器來實現特定的功能;
攔截器鏈(Interceptor Chain):攔截器鏈就是將攔截器按必定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其以前定義的順序被調用;
攔截器和過濾器的區別
自定義攔截器步驟
自定義攔截器類,該類實現HandlerInterceptor接口;
preHandle()
:訪問控制器前執行。返回true,訪問控制器;false則不訪問,此時,可以使用請求對象和響應對象經過請求轉發或重定向進行頁面跳轉;postHandle()
:訪問控制器後執行。若是此處進行頁面跳轉,則控制器返回的視圖名失效;afterCompletion()
:頁面加載後執行;package spitter.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 自定義攔截器 */ public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("攔截器前置方法執行..."); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("攔截器後置方法執行..."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("頁面加載完成,攔截器方法執行..."); } }
配置攔截器:;配置元素: <mvc:interceptors>
<!--配置攔截器--> <mvc:interceptors> <mvc:interceptor> <!--指定攔截的 URL--> <mvc:mapping path="/interceptor/myInterceptor"/> <!--指定不攔截的 URL <mvc:exclude-mapping path=""/>--> <!--配置攔截器對象--> <bean class="spitter.interceptor.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
攔截器可配多個,執行順序從上到下
此上,Spring MVC基礎學習已經完成。