1、 文件上传配置
1.1 点睛
文件上传是一个项目经常用到的功能,Spring MVC通过配置一个MultipartResolver来上传文件。
在Spring的控制器中,通过MultipartFile file来接受文件,通过MultipartFile[] files接受多个文件上传。
1.2 示例
1、 添加文件上传依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<!-- 编译和测试的时候用 -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
2、上传页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>upload page</title>
</head>
<body>
<div class="upload">
<form action="upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/><br/>
<input type="submit" value="上传">
</form>
</div>
</body>
</html>
3、添加跳转到upload页面的ViewController
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 重定向
registry.addRedirectViewController("index3", "index");
// 直接配置请求路径(index3)和页面(index.jsp)之间的映射。
// 无任何业务逻辑只是简单的业务逻辑可以这样子写,代码更简洁,管理集中
registry.addViewController("index2").setViewName("index");
registry.addViewController("forUpload").setViewName("upload");
}
4、MultipartResolver的配置
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(10000000);
return multipartResolver;
}
5、控制器
package com.chenfeng.xiaolyuh.controller;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController // 声明是一个控制器,并且返回时不需要@ResponseBody
public class FileUploadController {
@RequestMapping(value = "upload", method = RequestMethod.POST)
public Object getjson (MultipartFile file) throws IOException{
FileUtils.writeByteArrayToFile(new File("E:/upload/" + file.getOriginalFilename()), file.getBytes());
return "OK";
}
}
2、 自定义HttpMessageConverter(消息转换器)
2.1 点睛
HttpMessageConverter是用来处理request和response里的数据。Spring为我内置了大量的HttpMessageConverter,列如MappingJackson2HttpMessageConverter和StringHttpMessageConverter等。这里我们将演示自定义一个HttpMessageConverter,并注册到Spring MVC。
2.2 示例
2.2.1 自定义HttpMessageConverter
package com.chenfeng.xiaolyuh.message.converter;
import java.io.IOException;
import java.nio.charset.Charset;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.StreamUtils;
import com.chenfeng.xiaolyuh.entity.DemoObj;
/**
* 继承AbstractHttpMessageConverter类来实现自定义的HttpMessageConverter(消息转换器)
*/
public class MyHttpMessageConverter extends AbstractHttpMessageConverter<DemoObj> {
/**
*
* @Description 建立我们自定义的媒体类型"application/x-wisely"
*/
public MyHttpMessageConverter() {
super(new MediaType("application", "x-wisely", Charset.forName("UTF-8")));
}
/**
* 表明HttpMessageConverter(消息转换器)只处理DemoObj类
*/
@Override
protected boolean supports(Class<?> clazz) {
// 判断clazz类是不是DemoObj类或者是DemoObj的子类
return DemoObj.class.isAssignableFrom(clazz);
}
/**
* 重写readInternal方法,处理请求数据。代码表明我们处理有“-”隔开的数据,并转成DemoObj对象
*/
@Override
protected DemoObj readInternal(Class<? extends DemoObj> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
String temp = StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8"));
String[] tempArr = temp.split("-");
return new DemoObj(Long.parseLong(tempArr[0]), tempArr[1]);
}
/**
* 重写writeInternal方法,处理数据如何输出到response。此处,我么在原样输出前面加上“HELLO”
*/
@Override
protected void writeInternal(DemoObj t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
String out = "HELLO:" + t.getId() + "-" + t.getName();
outputMessage.getBody().write(out.getBytes());
}
}
2.2.2 配置
在addViewControllers方法中添加访问页面映射
registry.addViewController("converter").setViewName("converter");
配置自定义HttpMessageConverter,在Spring MVC里注册HttpMessageConverter有两种方法:
configureMessageConverters:覆盖掉Spring MVC默认注册的多个HttpMessageConverter
extendMessageConverters:仅添加一个自定义的HttpMessageConverter,不覆盖默认的HttpMessageConverter
@Bean
public MyHttpMessageConverter converter() {
return new MyHttpMessageConverter();
}
/**
* 覆盖掉Spring MVC默认注册的多个HttpMessageConverter
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
}
/**
* 仅添加一个自定义的HttpMessageConverter,不覆盖默认的HttpMessageConverter
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 添加一个自定义的消息转换
converters.add(converter());
}
2.2.3 控制器
package com.chenfeng.xiaolyuh.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.chenfeng.xiaolyuh.entity.DemoObj;
@Controller // 声明是一个控制器,并且返回时不需要@ResponseBody
public class ConverterController {
@RequestMapping(value = "/convert", produces = { "application/x-wisely" })// 自定义的媒体类型
@ResponseBody
public DemoObj convert(@RequestBody DemoObj demoObj) {
return demoObj;
}
}
2.2.4 页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HttpMessageConverter Demo</title>
</head>
<body>
<div id="resp"></div><input type="button" οnclick="req();" value="请求"/>
<script src="assets/js/jquery.js" type="text/javascript"></script>
<script>
function req(){
$.ajax({
url: "convert",
data: "1-wangyunfei", //数据格式和自定义的消息转换器一致
type:"POST",
contentType:"application/x-wisely", //媒体类型和消息转换器的一致
success: function(data){
$("#resp").html(data);
}
});
}
</script>
</body>
</html>