import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Maps;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import io.undertow.servlet.util.IteratorEnumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* 前后端分离时,使用json作为数据传输格式后,jfinal的getPara系列方法失效;
* 此拦截器预处理,将json转为Map,写入getParamerterMap, 不影响已有的getParam方法;
* <p> @Date : 2019/11/25 </p>
*
*/
public class JsonParamIntercept implements Interceptor {
@Override
public void intercept(Invocation inv) {
/**
* 1. 根据请求头预判json
* 2. 分解json,写入paramterMap
*/
WriteHttpServletRequestWrapper request = new WriteHttpServletRequestWrapper(inv.getController().getRequest());
if (request.getMethod().equalsIgnoreCase("post") && request.getContentType().contains("application/json")) {
Map<String, String> jsonParams = JSON.parseObject(inv.getController().getRawData(), new TypeReference<Map<String, String>>() {
});
request.init(jsonParams);
inv.getController().setHttpServletRequest(request);
}
inv.invoke();
}
class WriteHttpServletRequestWrapper extends HttpServletRequestWrapper {
Map<String, String[]> params = Maps.newHashMap();
/**
* Constructs a request object wrapping the given request.
*
* @param request the {@link HttpServletRequest} to be wrapped.
*
* @throws IllegalArgumentException if the request is null
*/
public WriteHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
params.putAll(request.getParameterMap());
}
public void init(Map<String, String> flatParams) {
for (Map.Entry<String, String> e : flatParams.entrySet()) {
params.put(e.getKey(), new String[] { e.getValue() });
}
}
@Override
public String getParameter(String name) {
String result = null;
for (Map.Entry<String, String[]> e : params.entrySet()) {
if (name.equalsIgnoreCase(e.getKey())) {
String[] values = e.getValue();
if (values.length == 1) {
result = values[0];
}
}
}
return result;
}
@Override
public Map<String, String[]> getParameterMap() {
return params;
}
@Override
public Enumeration<String> getParameterNames() {
final Set<String> parameterNames = new HashSet<>(params.keySet());
return new IteratorEnumeration<>(parameterNames.iterator());
}
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
}
}前后端分离项目,前后台通信已确定使用Json格式传输数据,但在Controller中无法直接使用getPara 系列方法,会有非常不方便,尝试利用拦截器集中对Json请求处理转成Map<String,Object> 放入request.paramterMap;
开发中发现,HttpServletRequest中没有对paramterMap的写操作,想必是为了达到只读的目,为了达到目的只能扩展HttpServletRequestWrapper.
不足之处:
几十行代码,外部的依赖好几个,没考虑扩展