关于Action参数注入的问题

因业务需要,使用JFinal搭建的接口服务,接入端参数需要进行加密传输。

原系统处理顺序为: Interceptor ->Validator  -> Controller,且入参采用注入方式。

加入一个前置拦截器用于加密参数预处理变更为:

参数解析拦截器 -> Interceptor ->Validator  -> Controller,

-----------------------------------------------------------------------------

参数解析拦截器主要处理的内容为:

1.参数解密

2.request内的参数修改 (通过继承HttpServletRequestWrapper)来保持参数到Controller的中继。

-------------------------------------------------------------------------------

现问题如下:

修改后的request对参数注入没有任何影响。所有的参数注入形式取值均无法取到,只能通过get系列方法来得到,所有Controller内的方法都需要对参数进行改造,不知有什么快捷的方式没。


-------------------------------------------------------------------------------

示例:


Interceptor:

// 参数值解密封装
Map<String,Object> paraMap = decryptData(c.get("data"));

// 入参修改中继
c.setHttpServletRequest(new EpRequestWrapper(c.getRequest(), paraMap ));

System.out.println(c.getRequest().getParameter("p1")); //可以取到值
System.out.println(c.get("p1")); //可以取到值



Validator :

   本身取值使用的get方法取值,参数值可以正常获取

Controller:

public void index(String p1,String p2){
    System.out.println(p1);  // 无法取到值
    System.out.println(get("p1")); // 可以获取到值
}




评论区

JFinal

2022-06-15 12:16

大概率是 EpRequestWrapper 中没有接管到某些 getter 方法,而参数注入调用了 getParameterMap 等方法去注入

参考 jfinal 的 JsonRequest:
https://gitee.com/jfinal/jfinal/blob/master/src/main/java/com/jfinal/core/paragetter/JsonRequest.java

这里头接管了 getParameterMap()、getParameter(...)、getParameterValues()、getParameterNames()

JsonRequest.java 中从 getInputStream() 开始往下的一些方法仅为转调,不必关心

azzcsimp

2022-06-15 13:11

@JFinal 这些接管得方法都有重新实现,在拦截器里把EpRequestWrapper替换成JsonRequest一样的结果。

azzcsimp

2022-06-15 13:36

@JFinal 进入到Controller,Request的类型已经变为JsonRequest/EpRequestWrapper,根据参数名也能获取到对应的参数值,唯独注入进来的一直是null。原始参数可以通过注入的形式直接使用。后续涉及变动修改的参数都还只能通过get(name)获取。

杜福忠

2022-06-15 14:41

@azzcsimp 使用 extends Handler 进行替换 HttpServletRequest
request = new EpRequestWrapper(request);
next.handle(target, request, response, isHandled);
https://jfinal.com/doc/2-7
因为 args参数值 比拦截器intercept 先执行,ParaProcessor 使用的还是未解密的request对象。
this.args = action.getParameterGetter().get(action, controller);
所以使用Handler即可。

azzcsimp

2022-06-15 16:18

@杜福忠 感谢,已成功解决问题。