fastjson 当使用Spring的@RequestBody报错

d5vmydt9  于 2021-11-27  发布在  Java
关注(0)|答案(19)|浏览(584)

{
"exception": {
"@type": "com.alibaba.fastjson.JSONException",
"localizedMessage": "syntax error, pos 6, json : userId=1&occUserId=1&stationId=1&stationNum=2G-W30&dateTime=2016-08-24&flag=1&type=1&source=1&lang=zh_CN",
"message": "syntax error, pos 6, json : userId=1&occUserId=1&stationId=1&stationNum=2G-W30&dateTime=2016-08-24&flag=1&type=1&source=1&lang=zh_CN",
"stackTrace": [
{
"className": "com.alibaba.fastjson.parser.DefaultJSONParser",
"fileName": "DefaultJSONParser.java",
"lineNumber": 1361,
"methodName": "parse",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.parser.DefaultJSONParser",
"fileName": "DefaultJSONParser.java",
"lineNumber": 1268,
"methodName": "parse",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.serializer.StringCodec",
"fileName": "StringCodec.java",
"lineNumber": 105,
"methodName": "deserialze",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.serializer.StringCodec",
"fileName": "StringCodec.java",
"lineNumber": 87,
"methodName": "deserialze",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.parser.DefaultJSONParser",
"fileName": "DefaultJSONParser.java",
"lineNumber": 614,
"methodName": "parseObject",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.JSON",
"fileName": "JSON.java",
"lineNumber": 339,
"methodName": "parseObject",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.JSON",
"fileName": "JSON.java",
"lineNumber": 307,
"methodName": "parseObject",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.JSON",
"fileName": "JSON.java",
"lineNumber": 270,
"methodName": "parseObject",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.JSON",
"fileName": "JSON.java",
"lineNumber": 370,
"methodName": "parseObject",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.JSON",
"fileName": "JSON.java",
"lineNumber": 452,
"methodName": "parseObject",
"nativeMethod": false
},
{
"className": "com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4",
"fileName": "FastJsonHttpMessageConverter4.java",
"lineNumber": 71,
"methodName": "read",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver",
"fileName": "AbstractMessageConverterMethodArgumentResolver.java",
"lineNumber": 197,
"methodName": "readWithMessageConverters",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor",
"fileName": "RequestResponseBodyMethodProcessor.java",
"lineNumber": 149,
"methodName": "readWithMessageConverters",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor",
"fileName": "RequestResponseBodyMethodProcessor.java",
"lineNumber": 127,
"methodName": "resolveArgument",
"nativeMethod": false
},
{
"className": "org.springframework.web.method.support.HandlerMethodArgumentResolverComposite",
"fileName": "HandlerMethodArgumentResolverComposite.java",
"lineNumber": 121,
"methodName": "resolveArgument",
"nativeMethod": false
},
{
"className": "org.springframework.web.method.support.InvocableHandlerMethod",
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 161,
"methodName": "getMethodArgumentValues",
"nativeMethod": false
},
{
"className": "org.springframework.web.method.support.InvocableHandlerMethod",
"fileName": "InvocableHandlerMethod.java",
"lineNumber": 128,
"methodName": "invokeForRequest",
"nativeMethod": false
},
{
"className": "org.springframework.web.method.annotation.ModelFactory",
"fileName": "ModelFactory.java",
"lineNumber": 139,
"methodName": "invokeModelAttributeMethods",
"nativeMethod": false
},
{
"className": "org.springframework.web.method.annotation.ModelFactory",
"fileName": "ModelFactory.java",
"lineNumber": 109,
"methodName": "initModel",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter",
"fileName": "RequestMappingHandlerAdapter.java",
"lineNumber": 805,
"methodName": "invokeHandlerMethod",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter",
"fileName": "RequestMappingHandlerAdapter.java",
"lineNumber": 738,
"methodName": "handleInternal",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter",
"fileName": "AbstractHandlerMethodAdapter.java",
"lineNumber": 85,
"methodName": "handle",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.DispatcherServlet",
"fileName": "DispatcherServlet.java",
"lineNumber": 963,
"methodName": "doDispatch",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.DispatcherServlet",
"fileName": "DispatcherServlet.java",
"lineNumber": 897,
"methodName": "doService",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.FrameworkServlet",
"fileName": "FrameworkServlet.java",
"lineNumber": 970,
"methodName": "processRequest",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.FrameworkServlet",
"fileName": "FrameworkServlet.java",
"lineNumber": 872,
"methodName": "doPost",
"nativeMethod": false
},
{
"className": "javax.servlet.http.HttpServlet",
"fileName": "HttpServlet.java",
"lineNumber": 646,
"methodName": "service",
"nativeMethod": false
},
{
"className": "org.springframework.web.servlet.FrameworkServlet",
"fileName": "FrameworkServlet.java",
"lineNumber": 846,
"methodName": "service",
"nativeMethod": false
},
{
"className": "javax.servlet.http.HttpServlet",
"fileName": "HttpServlet.java",
"lineNumber": 727,
"methodName": "service",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 303,
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 208,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "com.wafersystems.filter.SessionTimeOutFilter",
"fileName": "SessionTimeOutFilter.java",
"lineNumber": 58,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 241,
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 208,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "com.alibaba.druid.support.http.WebStatFilter",
"fileName": "WebStatFilter.java",
"lineNumber": 123,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 241,
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 208,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.springframework.orm.hibernate5.support.OpenSessionInViewFilter",
"fileName": "OpenSessionInViewFilter.java",
"lineNumber": 151,
"methodName": "doFilterInternal",
"nativeMethod": false
},
{
"className": "org.springframework.web.filter.OncePerRequestFilter",
"fileName": "OncePerRequestFilter.java",
"lineNumber": 107,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 241,
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 208,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.springframework.web.filter.CharacterEncodingFilter",
"fileName": "CharacterEncodingFilter.java",
"lineNumber": 197,
"methodName": "doFilterInternal",
"nativeMethod": false
},
{
"className": "org.springframework.web.filter.OncePerRequestFilter",
"fileName": "OncePerRequestFilter.java",
"lineNumber": 107,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 241,
"methodName": "internalDoFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.ApplicationFilterChain",
"fileName": "ApplicationFilterChain.java",
"lineNumber": 208,
"methodName": "doFilter",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.StandardWrapperValve",
"fileName": "StandardWrapperValve.java",
"lineNumber": 220,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.StandardContextValve",
"fileName": "StandardContextValve.java",
"lineNumber": 122,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.authenticator.AuthenticatorBase",
"fileName": "AuthenticatorBase.java",
"lineNumber": 503,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.StandardHostValve",
"fileName": "StandardHostValve.java",
"lineNumber": 170,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.valves.ErrorReportValve",
"fileName": "ErrorReportValve.java",
"lineNumber": 103,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.valves.AccessLogValve",
"fileName": "AccessLogValve.java",
"lineNumber": 950,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.core.StandardEngineValve",
"fileName": "StandardEngineValve.java",
"lineNumber": 116,
"methodName": "invoke",
"nativeMethod": false
},
{
"className": "org.apache.catalina.connector.CoyoteAdapter",
"fileName": "CoyoteAdapter.java",
"lineNumber": 421,
"methodName": "service",
"nativeMethod": false
},
{
"className": "org.apache.coyote.http11.AbstractHttp11Processor",
"fileName": "AbstractHttp11Processor.java",
"lineNumber": 1070,
"methodName": "process",
"nativeMethod": false
},
{
"className": "org.apache.coyote.AbstractProtocol$AbstractConnectionHandler",
"fileName": "AbstractProtocol.java",
"lineNumber": 611,
"methodName": "process",
"nativeMethod": false
},
{
"className": "org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor",
"fileName": "JIoEndpoint.java",
"lineNumber": 316,
"methodName": "run",
"nativeMethod": false
},
{
"className": "java.util.concurrent.ThreadPoolExecutor$Worker",
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 895,
"methodName": "runTask",
"nativeMethod": false
},
{
"className": "java.util.concurrent.ThreadPoolExecutor$Worker",
"fileName": "ThreadPoolExecutor.java",
"lineNumber": 918,
"methodName": "run",
"nativeMethod": false
},
{
"className": "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable",
"fileName": "TaskThread.java",
"lineNumber": 61,
"methodName": "run",
"nativeMethod": false
},
{
"className": "java.lang.Thread",
"fileName": "Thread.java",
"lineNumber": 662,
"methodName": "run",
"nativeMethod": false
}
]
}
}

mjqavswn

mjqavswn1#

@805728578 在http报文中,通过form表单提交的数据格式非标准JSON。(e.g userId=3&flag=1) 如果不用spring @requestbody注解就不会对走spring convertor,通过@RequestParam 直接从表单中获取数据或直接绑定数据对象。
@wenshao 这种格式的表单数据是否考虑支持
Caused by: com.alibaba.fastjson.JSONException: syntax error, pos 6, json : userId=3&flag=1 at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1361) at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1268) at com.alibaba.fastjson.serializer.StringCodec.deserialze(StringCodec.java:105) at com.alibaba.fastjson.serializer.StringCodec.deserialze(StringCodec.java:87) at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:614) at com.alibaba.fastjson.JSON.parseObject(JSON.java:339) at com.alibaba.fastjson.JSON.parseObject(JSON.java:307) at com.alibaba.fastjson.JSON.parseObject(JSON.java:270) at com.alibaba.fastjson.JSON.parseObject(JSON.java:370) at com.alibaba.fastjson.JSON.parseObject(JSON.java:452) at com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter.read(FastJsonHttpMessageConverter.java:190)

wfveoks0

wfveoks03#

@VictorZeng Jackson支持,Fastjson不计划支持吗?

crcmnpdw

crcmnpdw4#

看了一下Spring的源码的, Jackson自身是对这种数据格式支持的(e.g userId=3&flag=1)。

@SuppressWarnings("deprecation")
private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) {
    try {
        if (inputMessage instanceof MappingJacksonInputMessage) {
            Class<?> deserializationView = ((MappingJacksonInputMessage) inputMessage).getDeserializationView();
            if (deserializationView != null) {
                return this.objectMapper.readerWithView(deserializationView).withType(javaType).readValue(inputMessage.getBody());
            }
        }
        return this.objectMapper.readValue(inputMessage.getBody(), javaType);
    }
    catch (IOException ex) {
        throw new HttpMessageNotReadableException("Could not read document: " + ex.getMessage(), ex);
    }
}
6rqinv9w

6rqinv9w5#

@805728578 因为test8()的contentType是MediaType.APPLICATION_FORM_URLENCODED,这种类型提交的数据在http协议的body体中是非标准JSON的数据,通过Spring RequestBody注解获取到的数据格式是 userId=3&flag=1,FastJson暂时对这种数据无法解析。

2guxujil

2guxujil6#

1.FastJsonControllerTest增加

protected JSONObject params = new JSONObject();
@ModelAttribute
public void init(@requestbody(required=false)String body){
if(!StringUtil.isEmptyStr(body)){
params = JSON.parseObject(body);
}
log.info("--请求参数:"+body);
}

@RequestMapping(value = "/test7_8_9", method = {RequestMethod.POST, RequestMethod.GET},produces = {"text/plain", "application/*"})
public @responsebody Object test7_8_9(@RequestParam(defaultValue="0")long userId,RequestParam(defaultValue="0")int flag,String lang){
log.info("--请求参数{userId:"+userId+",flag:"+flag+"}json:"+params);
}

2.FastJsonHttpMessageConverterTest增加

@test
public void test7() throws Exception {
String jsonStr = "{"userId":3,"flag":1}";
mvc.perform((post("/fastjson/test7_8_9").characterEncoding("UTF-8").content(jsonStr).contentType(MediaType.APPLICATION_JSON))).andDo(print());
}
@test
public void test8() throws Exception {
mvc.perform((post("/fastjson/test7_8_9").characterEncoding("UTF-8")
.param("userId", "3")
.param("flag", "1")
.contentType(MediaType.APPLICATION_FORM_URLENCODED))).andDo(print());
}
@test
public void test9() throws Exception {
mvc.perform((post("/fastjson/test7_8_9").characterEncoding("UTF-8")
.param("userId", "3")
.param("flag", "1")
.contentType(MediaType.MULTIPART_FORM_DATA))).andDo(print());
}

对test7()/test9()支持,只是对test8()不支持,这是为什么呢?

g6baxovj

g6baxovj7#

@VictorZeng Jackson中支持

cu6pst1q

cu6pst1q8#

@805728578 这块场景Jackson/Gson/Genson 也支持吗 非标准JSON的数据
@wenshao 从 Spring Converter 中接收到的请求数据的格式 就是一个非标准JSON的数据(e.g userId=3&flag=1) FastJson目前不支持呀

xoshrz7s

xoshrz7s9#

@VictorZeng 参考一下Jackson/Gson/Genson的实现,和他们一致吧

e5nqia27

e5nqia2710#

@VictorZeng@wenshao 我测试是这样的结果,请考虑兼容,因为我的项目中支持两种混合方式

6yoyoihd

6yoyoihd11#

当使用post请求且使用@requestbody情况:
1.Content-Type:multipart/form-data;
2.Content-Type:application/x-www-form-urlencoded;
3.Content-Type:text/plain;

使用multipart/form-data或text/plain则OK
使用application/x-www-form-urlencoded将报错

q3aa0525

q3aa052512#

@VictorZeng 你将上述代码merge到项目中进行测试

e5nqia27

e5nqia2713#

@805728578 可以merge以上代码到项目中吗

mklgxw1f

mklgxw1f14#

@VictorZeng 你完全按照这样测试一下,你的testcase中都是单独使用,但是混合使用后就不支持APPLICATION_FORM_URLENCODED

b4qexyjb

b4qexyjb15#

  1. FastJsonControllerTest增加

protected JSONObject params = new JSONObject();
@ModelAttribute
public void init(@requestbody(required=false)String body){
if(!StringUtil.isEmptyStr(body)){
params = JSON.parseObject(body);
}
log.info("--请求参数:"+body);
}

@RequestMapping(value = "/test7_8", method = {RequestMethod.POST, RequestMethod.GET},produces = {"text/plain", "application/*"})
public @responsebody Object test7_8(@RequestParam(defaultValue="0")long userId,RequestParam(defaultValue="0")int flag,String lang){
log.info("--请求参数{userId:"+userId+",flag:"+flag+"}json:"+params);
}

2.FastJsonHttpMessageConverterTest增加

@test
public void test7() throws Exception {
String jsonStr = "{"userId":3,"flag":1}";
mvc.perform((post("/fastjson/test7_8").characterEncoding("UTF-8").content(jsonStr).contentType(MediaType.APPLICATION_JSON))).andDo(print());
}
@test
public void test8() throws Exception {
mvc.perform((post("/fastjson/test7_8").characterEncoding("UTF-8")
.param("userId", "3")
.param("flag", "1")
.contentType(MediaType.APPLICATION_FORM_URLENCODED))).andDo(print());
}

相关问题