(现有架构中的post过滤器只能处理json报文格式)
1、前端的请求报文需要传一个固定格式的json格式报文和一个文件
<Input.Group compact className='iptUpload'>
<Input style={{ width: 'calc(100% - 200px)', }} value={this.state.fileName} />
<Upload {...props} style={{ paddingLeft: 15 }} fileList={this.state.fileList}>
<Button htmlType="button" type="primary">选择文件</Button>
</Upload>
</Input.Group>
<span>
<Button className='uploadBts' type="primary"
disabled={disabled} onClick={() => {this.uploadClick()}}>上 传
</Button>
</span>
//上传(固定的json格式报文和文件作为请求报文)
uploadClick = () => {
console.log("上传")
const fileName = this.state.fileName;
const Operator = this.state.Operator;
const info = this.state.fileList[0];
let TransData = {
TransData: {
BaseInfo: {
TradeType: 'http',
TradeCode: 'S07',
TradeSeq: tools.getTradeSeq(),
TradeDate: tools.getToday(),
TradeTime: tools.getTime(),
Operator: Operator,
Key: tools.getKey(),
},
InputData: {
fileName: fileName,
fileByte: ""
}
}
};
const formData = new FormData();
formData.append('file', info.originFileObj);
formData.append('TransData', JSON.stringify(TransData));
axios({
method: 'POST',
contentType: false, //必须
processData :false, //用于对data参数进行序列化处理 这里必须false
url: url + '/fileUrl/upload',
data: formData,
}).then(response => {
console.log(response)
}).catch(response => {
console.log(response)
})
}
页面请求的内容显示如下:
(备注:file是文件,TransData是json的报文)
2、判断上传的表单是普通表单(固定json格式报文)还是带文件的表单,如果是带文件的表单(enctype="multipart/form-data")
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//拦截非post请求
this.interceptOtherRequest(servletRequest, servletResponse);
//判断上传的表单是普通表单还是带文件的表单,如果是带文件的表单(enctype="multipart/form-data")
if (ServletFileUpload.isMultipartContent((HttpServletRequest) servletRequest)) {
//处理request的请求报文数据,上传file文件,同时获取json报文
String requestMsg = HandleFileForm.doHandleRequestMessage(servletRequest);
//将json报文放到servletRequest中,继续原来的流程
HandleBodyRequest.doBodyMessage(servletRequest, requestMsg);
}
//过滤post请求
this.filterPostRequest(servletRequest, servletResponse, filterChain);
}
3、处理form表单的请求数据,file文件上传,返回json
package com.model;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* title: HandleFileForm
* description: 处理form表单的请求数据
*/
public class HandleFileForm {
public static String doHandleRequestMessage(ServletRequest servletRequest) throws IOException{
String requestMessage = "";
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
try {
//创建上传文件的保存目录
String uploadpath = new File("").getCanonicalPath().replace("chmmce","upLoadFile");//.concat("\\upLoadFile")
File uploadfile = new File(uploadpath);
//如果目录不存在就创建这样一个目录
if (!uploadfile.exists()) {
uploadfile.mkdir();
}
//创建一个解析器工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File(uploadpath));
//文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//设置编码格式
upload.setHeaderEncoding("UTF-8");
//解析请求,将表单中每个输入项封装成一个FileItem对象
List<FileItem> itemList = upload.parseRequest(httpServletRequest);
for (FileItem item : itemList) {
if (!item.isFormField()) {
//处理请求httpServletRequest中的文件
String uploadFileName = item.getName();//上传的文件名
//返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。
if (uploadFileName.trim().equals("") || uploadFileName == null){
continue;
}
//获得上传的文件名,例如/img/girl/ooa.jpg,只需要ooa,其前面的后面的都不需要
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//获得文件的后缀名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
//可以使用UUID(唯一通用识别码)来保证文件名的统一
String uuidFileName = UUID.randomUUID().toString();
//获得文件上传的流
InputStream inputStream = item.getInputStream();
//创建一个文件输出流
FileOutputStream fos = new FileOutputStream(uploadpath + "/" + uuidFileName +"."+ fileExtName);
//创建一个缓冲区
byte[] buffer = new byte[1024 * 1024];
//判断是否读取完毕
int len = 0;
//如果大于0,说明还存在数据
while ((len=inputStream.read(buffer)) > 0){
fos.write(buffer,0,len);
}
//关闭流
fos.close();
inputStream.close();
item.delete();//上传成功,清除临时文件
String ffileName = item.getName();
} else {
//处理请求httpServletRequest中的json报文
String name = item.getFieldName();
requestMessage = item.getString("UTF-8");//处理乱码
}
}
} catch (IOException | FileUploadException e) {
throw new IOException();
}
return requestMessage;
}
}
4、处理request的请求报文数据
package com.model;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
/**
* title: HandleBodyRequest
* description: 将json报文放入HttpServletRequest
*/
public class HandleBodyRequest {
public static void doBodyMessage(ServletRequest servletRequest, String requestMsg) throws IOException{
try {
if (servletRequest instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String contentType = request.getContentType().split(";")[0];
//body形式(json)
if (contentType.equals(MediaType.MULTIPART_FORM_DATA_VALUE)) {
//获取request的body参数
String postContent = getBody(requestMsg);
//如果body中存在数据放入HttpServletRequest
if (StringUtils.isNotEmpty(postContent)) {
//将参数放入重写的方法中
request = new BodyRequestWrapper(request, postContent);
}
}
servletRequest = request;
}
}catch (IOException ex) {
throw new IOException();
}
}
//Request的json报文
public static String getBody(String requestMsg) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(requestMsg.getBytes("UTF-8"));
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int read = -1;
while ((read = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, read);
}
}
} catch (IOException ex) {
throw new IOException();
} finally {
if (inputStream != null) {
inputStream.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
}
return stringBuilder.toString();
}
}
5、将新的请求的json报文放入ServletRequest的重写的方法中
package com.model;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class BodyRequestWrapper extends HttpServletRequestWrapper {
private String body;
public BodyRequestWrapper(HttpServletRequest request, String context) {
super(request);
body = context;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
return servletInputStream;
}
}
6、主要使用到的依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>