1、首先需要重写HttpServletRequest, 能够让我们对Parameter做操作(格式化需要FastJSON)
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.jfinal.kit.HttpKit; import com.jfinal.kit.StrKit; import com.jfinal.render.ContentType; public class ParameterRequestWrapper extends HttpServletRequestWrapper { private HttpServletRequest request; private Map<String, String[]> params = new HashMap<>(); /** * @param request */ @SuppressWarnings("unchecked") public ParameterRequestWrapper(HttpServletRequest request) { super(request); this.params.putAll(request.getParameterMap()); this.request = request; initParameters(this.request); } /** * 重写getParameterMap, 设置map从当前类获取 * 主要是jfinal的参数注入是从getParameterMap中获取注入的 */ @Override public Map<String, String[]> getParameterMap() { return params; } /** * 重写getParameter, 设置参数从当前类获取 */ @Override public String getParameter(String name) { String[] values = params.get(name); if (values == null || values.length == 0) { return null; } return values[0]; } /** * 获取当前类参数 */ public String[] getParameterValues(String name) { return params.get(name); } /** * 新增参数 * @param otherParams */ public void addParameter(Map<String, Object> otherParams) { for (Entry<String, Object> entry : otherParams.entrySet()) { addParameter(entry.getKey(), entry.getValue()); } } /** * 新增参数 * @param name * @param value */ public void addParameter(String name, Object value) {// 增加参数 if (value != null) { if (value instanceof String[]) { params.put(name, (String[]) value); } else if (value instanceof String) { params.put(name, new String[] { (String) value }); } else { params.put(name, new String[] { String.valueOf(value) }); } } } /** * 初始化params, 格式化JSON * @param request */ public void initParameters(HttpServletRequest request) { String contentType = request.getContentType(); if (StrKit.isBlank(contentType)) return; if (contentType.equals(ContentType.JSON.toString())) { String rawData = HttpKit.readData(request); if (StrKit.isBlank(rawData)) return; Object requestParamObject = convertObject(rawData); if (requestParamObject == null) return; if (requestParamObject instanceof JSONObject) { JSONObject jsonObject = (JSONObject) requestParamObject; for (Entry<String, Object> entry : jsonObject.entrySet()) { addParameter(entry.getKey(), entry.getValue()); } } else if (requestParamObject instanceof JSONArray) { } else return; } } /** * 入参转为JSON * @param rawData * @return */ public Object convertObject(String rawData) { Object requestParamObject = null; try { requestParamObject = JSON.parseObject(rawData); } catch (Exception e) { requestParamObject = null; } return requestParamObject; } }
2、编写BaseJsonHandler更改自定义的HttpServletRequest
public class BaseJsonHandler extends Handler{ @Override public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) { if (target.indexOf(".") == -1) { request = new ParameterRequestWrapper(request); } next.handle(target, request, response, isHandled); } }
3、在config中加入BaseJsonHandler
@Override public void configHandler(Handlers me) { me.add(new BaseJsonHandler()); }
使用:
1、依然与正常的参数注入一样使用, Controller的方法添加入参
2、具体的实现思路为:
jfinal的参数注入是从HttpServletRequest Parameter中根据key获取值,但是原生的HttpServletRequest是不允许修改Parameter的, 所以需要重写, 重写后我们就可以拦截到json请求后从使用HttpKit.readData方法获取到json字符串,对json字符串进行格式化再放到Parameter中,这样就可以正常注入 到方法的入参中
if (target.indexOf(".") == -1) {
request = new ParameterRequestWrapper(request);
}
只在必要的时候做 wrapper 保障了性能。总体上简洁有力,感谢分享