RequestHandler
package com.chinadaas.platform.servicecenter.mycommon.handler;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
@Getter
@Setter
public class RequestHandler extends HttpServletRequestWrapper {
private String rawJson;
private String form;
private String query;
public static RequestHandler getInstance(HttpServletRequest request) {
if (request instanceof StandardMultipartHttpServletRequest) {
request = ((StandardMultipartHttpServletRequest) request).getRequest();
}
return (RequestHandler)request;
}
public RequestHandler(HttpServletRequest request) throws IOException {
super(request);
StringBuilder sb = new StringBuilder();
InputStream ins = request.getInputStream();
BufferedReader isr = null;
try{
// rawJson case
if(ins != null){
isr = new BufferedReader(new InputStreamReader(ins, Charset.defaultCharset()));
char[] charBuffer = new char[128];
int readCount;
while((readCount = isr.read(charBuffer)) != -1){
sb.append(charBuffer,0,readCount);
}
setRawJson(sb.toString());
}
// check getParameterMap
Map<String, String[]> tParamMap = request.getParameterMap();
if (!(Objects.nonNull(tParamMap) && tParamMap.size() > 0)) {
return;
}
Map<String, String> paramMap = Maps.newHashMap();
tParamMap.entrySet().forEach(param -> {
/* Array T String */
String[] valArr = param.getValue();
StringBuilder sbVal = new StringBuilder();
for (String val : valArr) {
sbVal.append(val).append(",");
}
// clean last ","
String val = sbVal.substring(0, sbVal.length()-1);
paramMap.put(param.getKey(), val);
});
// form case
// business try catch
try {
Collection<Part> parts = request.getParts();
Map<String, String> form = Maps.newHashMap();
parts.forEach(part -> {
String paramKey = part.getName();
String paramVal = paramMap.get(paramKey);
paramMap.remove(paramKey);
form.put(paramKey, paramVal);
});
setForm(JSON.toJSONString(form));
}
catch (Exception e) {
e.printStackTrace();
// no form-data
}
// query case
setQuery(JSON.toJSONString(paramMap));
System.out.println(1);
}
finally {
if(isr != null) {
isr.close();
}
}
}
@Override
public ServletInputStream getInputStream() {
try {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(rawJson.getBytes(Charset.defaultCharset()));
return new ServletInputStream() {
@Override
public int read() {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}catch (Exception e){
e.printStackTrace();
return null;
}
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
- 注意:HttpServletRequest 请求中的 body 内容仅能调用 request.getInputStream(), request.getReader() 和request.getParameter("key") 方法读取一次,重复读取会报 java.io.IOException: Stream closed 异常。
- 原来两个同名参数的值都能在后台拿到,难怪request.getParamterMap()方法的返回值类型是Map<String, String[]>,第二个String[]数组就能很好地处理同名参数。
Filter
package com.chinadaas.platform.servicecenter.mycommon.filter;
import com.chinadaas.platform.servicecenter.mycommon.handler.RequestHandler;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(filterName = "myFilter", urlPatterns = "/exec/convert/service/*")
public final class RequestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
RequestHandler request = new RequestHandler((HttpServletRequest) servletRequest);
filterChain.doFilter(request, servletResponse);
}
@Override
public void destroy() {
}
}
Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* @author Lux Sun
* @date 2020/7/8
*/
@SpringBootApplication
@ServletComponentScan("com.chinadaas.platform.servicecenter.mycommon")
public class DspServiceExecutorApplication {
public static void main(String[] args) {
SpringApplication.run(DspServiceExecutorApplication.class, args);
}
}