SpringMVC:统一异常处理与文件上传下载

本文介绍了SpringMVC中如何进行统一异常处理,包括使用SimpleMappingExceptionResolver、实现HandlerExceptionResolver接口以及应用@ExceptionHandler注解。同时,讲解了文件上传和下载的实现,重点在于文件下载时的HTTP响应头设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

异常处理

  • SimpleMappingExceptionResolver
  • HandlerExceptionResolver接口自定义异常
  • 使用@ExceptionHandler注解

文件上传下载
如果是图片可以参考另外一篇Spring bootspring boot单/多图片上传并回显

1.SimpleMappingExceptionResolver类

需要提前在springmvc-servlet.xml中配置异常类于view的对应关系

2.HandlerExceptionResolver接口

用于解析请求处理过程中所产生的 异常
创建一个该接口的实现类并重写方法

package exception中定义MyExceptionHandeler类,并且在Springmvc配置中托管该bean
< bean class=“exception.MyExceptionHandler”/>

package exception;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
public class MyExceptionHandler implements HandlerExceptionResolver {
	@Override
public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
			Exception arg3) {
		   	Map<String, Object> model = new HashMap<String, Object>();  
	        model.put("ex", arg3);    
	        // 根据不同错误转向不同页面(统一处理),即异常与view的对应关系  
	        if(arg3 instanceof MyException) {  
	            return new ModelAndView("my-error", model);  
	        }else if(arg3 instanceof SQLException) {  
	            return new ModelAndView("sql-error", model);  
	        } else {  
	            return new ModelAndView("error", model);  
	        }  
	}
}
3.使用@ExceptionHandler注解

创建一个BaseController类,并创建一个方法,使用该注解声明异常处理方法

public abstract class BaseController {
	 /** 基于@ExceptionHandler异常处理 */  
	@ExceptionHandler
    public String exception(HttpServletRequest request, Exception ex)  {  
		request.setAttribute("ex", ex);
        // 根据不同错误转向不同页面,即异常与View的对应关系  
        if(ex instanceof SQLException) { 
        	return "sql-error";
        }else if(ex instanceof MyException) { 
        	return "my-error";
        } else {  
        	return "error";
        }  
    }  
}

之后在所有需要异常处理的Controller都继承BaseController类。不需要配置

文件上传与下载

基于表单的文件上传与下载:再form中一定不能忘记enctype=“multipart/form-data” (以二进制流的方式来处理表单数据,并将文件域指定文件的内容封装到请求参数中
接收用MultipartFile,该接口的方法如下:

byte[] getBytes():以字节数组的形式返回文件的内容。
String getContentType():返回文件的内容类型。
InputStream getInputStream():返回一个InputStream,从中读取文件的内容。
String getName():返回请求参数的名称。
String getOriginalFilename():返回客户端提交的原始文件名称。
long getSize():返回文件的大小,单位为字节。
boolean isEmpty():判断被上传文件是否为空。
void transferTo(File destination):将上传文件保存到目标目录下。

文件上传

	/**
	 * 单文件上传
	 */
	@RequestMapping("/onefile")
    public String oneFileUpload(@RequestParam("wenjian") MultipartFile wenjian,
	    						 HttpServletRequest request){
	String realpath = request.getServletContext().getRealPath("uploadfiles");
	String fileName = wenjian.getOriginalFilename(); 
	File targetFile = new File(realpath, fileName); 
	if(!targetFile.exists()){  
	          targetFile.mkdirs();  
	      } 
	//上传 
	      try {   
	      	wenjian.transferTo(targetFile);
	      	logger.info("成功");
	      } catch (Exception e) {  
	          e.printStackTrace();  
	      }
	return "showOne";
	  }

SpringMVC配置文件 springmvc-servlet.xml

<!-- 配置MultipartResolver 用于文件上传 使用spring的CommosMultipartResolver -->  
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"  
    p:defaultEncoding="UTF-8"  
    p:maxUploadSize="5400000"  
    p:uploadTempDir="fileUpload/temp" 
 > 
  <!--D:\spring mvc workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileUpload  -->  
</bean> 
<!-- defaultEncoding="UTF-8" 是请求的编码格式,默认为iso-8859-1
maxUploadSize="5400000" 是允许上传文件的最大值,单位为字节
uploadTempDir="fileUpload/temp" 为上传文件的临时路径 --> 

文件下载:利用程序实现下载

下载前要设置报头:
response.setHeader(“Content-Type”, “application/x-msdownload” );
response.setHeader(“Content-Disposition”, “attachment; filename=” + filename);

Controller:

package controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class FileDownController {
	// 得到一个用来记录日志的对象,这样打印信息的时候能够标记打印的是那个类的信息
	private static final Log logger = LogFactory.getLog(FileDownController.class);
	/**
	 * 显示要下载的文件
	 */
	@RequestMapping("showDownFiles")
	public String show(HttpServletRequest request, Model model){
		//从workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ch7\下载
		String realpath = request.getServletContext().getRealPath("uploadfiles");
		File dir = new File(realpath);
		File files[] = dir.listFiles();
		//获取该目录下的所有文件名
		ArrayList<String> fileName = new ArrayList<String>();
		for (int i = 0; i < files.length; i++) {
			fileName.add(files[i].getName());
		}
		model.addAttribute("files", fileName);
		return "showDownFiles";
	}
	/**
	 * 执行下载
	 */
	@RequestMapping("down")
	public String down(@RequestParam String filename, HttpServletRequest request, HttpServletResponse response){
		String aFilePath = null; //要下载的文件路径
		FileInputStream in = null; //输入流
		ServletOutputStream out = null; //输出流
		try {
			//从workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps下载
			aFilePath = request.getServletContext().getRealPath("uploadfiles");
			//设置下载文件使用的报头
			response.setHeader("Content-Type", "application/x-msdownload" );
			response.setHeader("Content-Disposition", "attachment; filename="
					+ toUTF8String(filename));
			// 读入文件
			in = new FileInputStream(aFilePath + "\\"+ filename); 
			//得到响应对象的输出流,用于向客户端输出二进制数据
			out = response.getOutputStream();
			out.flush();
			int aRead = 0;
			byte b[] = new byte[1024];
			while ((aRead = in.read(b)) != -1 & in != null) {
				out.write(b,0,aRead);
			}
			out.flush();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
		} 
		logger.info("下载成功");
		return null;
	}
	/**
	 * 下载保存时中文文件名字符编码转换方法
	 */
	public  String toUTF8String(String str){
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for(int i = 0; i < len; i++){
			//取出字符中的每个字符
			char c = str.charAt(i);
			//Unicode码值在0-255之间,不作处理
			if(c >= 0 && c <= 255){
				sb.append(c);
			}else{//转换UTF-8编码
				byte b[];
				try {
					b = Character.toString(c).getBytes("UTF-8");
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
					b = null;
				}
				//转换为%HH的字符串形式
				for(int j = 0; j < b.length; j ++){
					int k = b[j];
					if(k < 0){
						k &= 255;
					}
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值