天天看點

springmvc-檔案上傳 攔截器 全局異常 傳回json 處理流程

spring mvc上傳

  1. 添加項目依賴
    <!-- 上傳元件 -->
    <dependency>
    	<groupId>commons-io</groupId>
    	<artifactId>commons-io</artifactId>
    	<version>2.5</version>
    </dependency>
    <dependency>
    	<groupId>commons-fileupload</groupId>
    	<artifactId>commons-fileupload</artifactId>
    	<version>1.3.2</version>
    </dependency>
               
  2. 添加上傳限制
    <!-- upload -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    	<property name="maxUploadSize">
    		<!-- 上傳檔案的大小 10M -->
    		<value>10485760</value>
    	</property>
    </bean>
               
  3. 添加上傳邏輯
    • 上傳的表單必須為post請求,并且設定enctype=“multipart/form-data”
    • 在controller 方法裡面添加類型

      以下是重要代碼

      file.getOriginalFilename();//檔案名稱
      request.getServletContext().getRealPath("/");//項目路徑
      request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();//項目URL
                 

spring mvc 攔截器

  1. 聲明一個類,并且實作HandlerInterceptor
  2. 配置攔截器,在spring mvc的配置檔案加上
    <mvc:interceptors>  
       <!--  使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor将攔截所有的請求   -->
    	<!-- <bean class="xxxx"/> -->   
    	<mvc:interceptor>  
    		<!-- 進行攔截:/**表示攔截所有controller -->
    		<!-- 進行攔截:/*是會分層級的 -->
    		<mvc:mapping path="/**" />
    	   <!-- 不進行攔截 -->
    		<mvc:exclude-mapping path="/index.html"/>
    		<bean class="xxxx"/>  
    	</mvc:interceptor>  
    </mvc:interceptors>   
               

spring mvc 全局異常

  1. 聲明一個類,并且實作HandlerExceptionResolver
  2. 把這個類放到spring 容器裡面

spring mvc 傳回json

  1. 添加項目依賴
    <dependency>
    	<groupId>com.fasterxml.jackson.core</groupId>
    	<artifactId>jackson-databind</artifactId>
    	<version>2.8.6</version>
    </dependency>
    <dependency>
    	<groupId>commons-beanutils</groupId>
    	<artifactId>commons-beanutils</artifactId>
    	<version>1.9.2</version>
    </dependency>
    <dependency>
    	<groupId>org.codehaus.jackson</groupId>
    	<artifactId>jackson-mapper-asl</artifactId>
    	<version>1.9.13</version>
    </dependency>
    <dependency>
    	<groupId>org.codehaus.jackson</groupId>
    	<artifactId>jackson-core-asl</artifactId>
    	<version>1.9.13</version>
    </dependency>
    
               
  2. 在方法上添加@ResponseBody

spring mvc 處理流程

​ 1.使用者發送請求至 前端控制器DispatcherServlet。

​ 2.前端控制器DispatcherServlet收到請求後調用處理器映射器HandlerMapping。

​ 3.處理器映射器HandlerMapping根據請求的Url找到具體的處理器,生成處理器對象Handler及處理器攔截器HandlerIntercepter(如果有則生成)一并傳回給前端控制器DispatcherServlet。

​ 4.前端控制器DispatcherServlet通過處理器擴充卡HandlerAdapter調用處理器Controller。

​ 5.執行處理器(Controller,也叫後端控制器)

​ 6.處理器Controller執行完後傳回ModelAnView。

​ 7.處理器映射器HandlerAdapter将處理器Controller執行傳回的結果ModelAndView傳回給前端控制器DispatcherServlet。

​ 8.前端控制器DispatcherServlet将ModelAnView傳給視圖解析器ViewResolver。

​ 9.視圖解析器ViewResolver解析後傳回具體的視圖View。

​ 10.前端控制器DispatcherServlet對視圖View進行渲染視圖(即:将模型資料填充至視圖中)

​ 11.前端控制器DispatcherServlet響應使用者。

在之前的項目中:

pom添加依賴:

<!-- 上傳元件 -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.5</version>
</dependency>
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.2</version>
</dependency>
           

bean配置中添加:

<!-- upload -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<property name="maxUploadSize">
		<!-- 上傳檔案的大小 10M -->
		<value>10485760</value>
	</property>
</bean>
           

uploadController:上傳頁面跳轉回顯

package com.liuxi.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class UploadController {

	@RequestMapping("/toUpload")
	private String toUpload() {

		return "upload";

	}

	@RequestMapping("upload")
	private String upload(@RequestParam(required = true) MultipartFile file, HttpServletRequest request, ModelMap map)
			throws IOException {

		String filename = file.getOriginalFilename();// 擷取檔案名
		String path = request.getServletContext().getRealPath("/");// 項目路徑
		String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
				+ request.getContextPath();// 項目url

		String filename2 = uploadFile(file, filename, path, url);
		map.put("imgURL", filename2);

		return "upload";
	}

	private String uploadFile(MultipartFile file, String filename, String path, String url)
			throws IOException, FileNotFoundException {
		System.out.println(url);

		System.out.println(filename);
		System.out.println(path);

		// 上傳到檔案夾
		path += "/upload/";
		File file2 = new File(path);
		if (!file2.exists()) {
			file2.mkdirs();
		}

		// 随機生成檔案名,使用時間戳
		String hz = filename.substring(filename.lastIndexOf("."));

		String filename2 = new Date().getTime() + hz;

		// 上傳檔案,寫io流
		InputStream inputStream = file.getInputStream();

		OutputStream outputStream = new FileOutputStream(path + filename2);

//		byte[] bs = new byte[1024];
//
//		int i = -1;
//		while ((i = inputStream.read(bs)) != -1) {
//			outputStream.write(bs, 0, i);
//		}
//		outputStream.flush();
//		outputStream.close();
//		inputStream.close();
//

		FileCopyUtils.copy(inputStream, outputStream);
		return "/upload/" + filename2;
	}
}

           

上傳頁面:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
	我是上傳頁面
	<br>
	<form action="${pageContext.request.contextPath}/upload.do"
		method="post" enctype="multipart/form-data">
		檔案:<input type="file" name="file"> <input type="submit">

		<img src="${pageContext.request.contextPath}${imgURL}" alt="上海鮮花港 - 郁金香" />
	</form>
</body>
</html>
           

攔截器:

實作攔截器類:

package com.liuxi.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class FirstInterceptor implements HandlerInterceptor {

	// 前
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("preHandle");
		response.sendRedirect(request.getContextPath() + "/ toLogin.do");
		return false;
	}

	// 請求
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("postHandle");

	}

	// 後
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("afterCompletion");

	}

}

           

配置攔截器,在spring mvc的配置檔案加上:

<mvc:interceptors>
		<!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor将攔截所有的請求 -->
		<!-- <bean class="xxxx"/> -->
		<mvc:interceptor>
			<!-- 進行攔截:/**表示攔截所有controller -->
			<!-- 進行攔截:/*是會分層級的 -->
			<mvc:mapping path="/**" />
			<!-- 不進行攔截 -->
			<mvc:exclude-mapping path="/toLogin.do" />
			<bean class="com.liuxi.interceptor.FirstInterceptor" />
		</mvc:interceptor>
	</mvc:interceptors>

           

全局異常:

logincontroller:

package com.liuxi.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {

	@RequestMapping("toLogin")
	private String toLogin() {
		int i = 1 / 0;
		return "login";
	}
}

           

方法一:

package com.liuxi.resolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

@Component
public class FirstResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		ModelAndView modelAndView = new ModelAndView("error");
		return modelAndView;
	}

}
           

全局異常2:

package com.liuxi.resolver;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice /// 原本@ExceptionHandler隻是目前controller的異常處理類,隻要在類型上加上@controllerAdvice,就會變成全局異常處理類。
public class SecondResolver {

	@ExceptionHandler
	private String aaa(Exception exception) {// 添加上@ExceptionHandler之後就是一個全局異常處理方法
		exception.printStackTrace();// 直接輸出異常到控制台
		return "error";// 和controller 一樣,因為視圖解析器在這個地方一樣生效
	}
}

           

傳回json:

添加項目依賴:

<!-- json -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.6</version>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.9.2</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.13</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-asl</artifactId>
			<version>1.9.13</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.71</version>
		</dependency>


           

jsonController:

package com.liuxi.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;

@Controller
public class JsonController {

	@RequestMapping("toJsonReturn")
	private String toJsonReturn() {
		return "json";// 因為配置視圖解析器,直接傳回字元串,請求就會跳轉到對應的頁面
	}

	@RequestMapping("jsonReturn")
	@ResponseBody // 傳回的資料,轉成字元串傳回,添加上了@ResponseBody.視圖解析器就不再生效了。
	private String jsonReturn() {

		Map map = new HashMap();
		map.put("key", "value");
		return JSON.toJSONString(map);
	}

	@RequestMapping("jsonReturnMap")
	@ResponseBody
	private Map jsonReturnMap() {

		Map map = new HashMap();
		map.put("key", "value");
		return map;
	}
}

           

繼續閱讀