异常处理
- 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();
}
}