JFinal1.9参数丢失

桀鹰 发布于 2016/12/29 11:36
阅读 270
收藏 0

@JFinal 你好,想跟您请教个问题:

        我们公司的项目使用的是JFinal1.9版本,发现会偶尔(同样的访问也不是每次都出现)出现参数丢失的问题,这个问题出现有快一年了,今天跟进了下,发现tomcat的日志里是有参数的:[29/Dec/2016:08:58:04 +0800] "POST  /api/v2/case/index?app_key=f1c18i2otirc0004&client_id=7ca1aukb5pri00ba&net=3g&versionName=4.5.2&versionCode=118&access_token=4f8ebca1-c13e-42f0-806c-4e52f329437b

但是JFinal打印的日志里却没有:

JFinal action report -------- 2016-12-29 08:58:04 ------------------------------
Controller  : camel.plugin.yx.controller.api.newcase.CaseController.(CaseController.java:1)
Method      : index
UrlPara     : index
Interceptor : camel.core.aop.DevInterceptor.(DevInterceptor.java:1)
              camel.core.aop.GlobalInterceptorStack.(GlobalInterceptorStack.java:1)
              com.jfinal.ext.interceptor.SessionInViewInterceptor.(SessionInViewInterceptor.java:1)
              dynamic.interceptor.TrackPageviewInterceptor.(TrackPageviewInterceptor.java:1)
              camel.core.log.SysLogInterceptor.(SysLogInterceptor.java:1)
              camel.core.aop.SecretInterceptor.(SecretInterceptor.java:1)
--------------------------------------------------------------------------------
ai.getActionKey(): /api/v2/case

我看了项目中我们写的所有的Handler没有对request删除参数的代码,查看JFinal源码也没有发现什么问题,还请大师指教,谢谢!

加载中
0
JFinal
JFinal

从现象上来看,参数到达 tomcat,并且 tomcat 日志也打印出来了参数,此时 tomcat 会解析参数并且封装成 HttpServletRequest 对象,注意检查一下,自己有没有在 Handler 或者  web.xml 中定义的 Filter 中对 HttpServletRequest 这个对进行过二次封装,类似于 Mock 类这样的封装

还要注意一下有没有 Handler、Filter 中利用反射对 HttpServletRequest 对象进行过干预,很可能是这个 request 对象到达 jfinal 的时候参数已然没有了,要知道 jfinal 的 action report 仅仅只是简单地调用一下 request.getParameter(...) 输出一下而已,这样的调用,参数如果存在那就会输出,没有就是没有

0
JFinal
JFinal
特别注意看一下,请求是否被做了 302 重定向,重定向会丢失所有参数,这个重定向并不是 jfinal 会去做的,而是 tomcat 有这个可能,具体原因可以参考这篇贴子:https://www.oschina.net/question/186435_245225
JFinal
JFinal
回复 @桀鹰 : jfinal 对参数本质上是没有处理,因为 getPara(...) 这些方法都仅仅是转调了底层的 HttpServletRequset 对象的 getParameter(...) 方法,这种极薄的封装出错的可能性几乎为 0
桀鹰
我查看了一下tomcat的日志,在这个访问日志的前后都是200状态码的记录,没有一条302的。即使是重定向过来的url中的参数不应该取不到啊。
0
JFinal
JFinal
其实,HttpSerlvetRequest request 这个对象中的参数要删除才是件麻烦的事,因为该对象存放参数的 Map 是只读的,根本不让删,也不让写,要删的办法通常是在 Filter 或者 Handler 中将原来的 request 对象丢弃,创建一个新的 request 来代替
桀鹰
回复 @JFinal : 是的,开新线程的目的是想做一些和响应无关的日志记录工作,这是属于业务层的工作,但是开发人员水平不到,将controller传了进去。
JFinal
JFinal
回复 @桀鹰 : 每一个 controller 都处在一个独立的线程之中,所以不必对 controller 创建新的线程,如果为了在后续业务层调用返回之前响应客户端,将业务层置于新建线程中是可以的
桀鹰
回复 @JFinal : 最终还是自己代码的bug导致的,谢谢您之前的悉心回复。
桀鹰
回复 @JFinal :代码中将Controller传到新启动的线程,并且在新线程中调用了获得参数的方法,如果主线程已经结束,request对象会被tomcat回收再利用的,新启动的线程有时会还未结束,会使用已经被回收request,调用getParameter方法,将Request对象的parametersParsed置为true,下个请求使用这个request对象就无法解析参数,导致参数丢失
JFinal
JFinal
回复 @桀鹰 : 换 tomcat 高版本,tomcat 的代码是比较乱的,出 bug 是常有的事
下一页
返回顶部
顶部