【问题标题】:Json object and Spring controller the request sent by the client was syntactically incorrect (bad request)Json 对象和 Spring 控制器客户端发送的请求在语法上不正确(错误请求)
【发布时间】:2014-08-05 21:49:35
【问题描述】:

我想分享以下我花了大约两天时间修复它的经验: 工具:Spring MVC 3.2.3、Roo 1.2.4、Java 7。

我尝试将 Json 对象传递给我的控制器,如下所示:

.js 文件

    var params= { 
        "eItemId" : p1,
        "eItemCode" : p2, 
        "eItemPartNbr" : p3, 
        "eItemDesc" : p4,
        "uomItemSlctId" : p5,
        "eForAnyCompany" : flag 
};

$.ajax({
    type: "POST",
    url: "/item/saveitem",
    contentType: "application/json",
    dataType: "json",
    data: JSON.stringify(params),
    cache: false,.....

我对控制器方法签名进行了很多修改但没有成功,最后我从一开始就保持简单:

    @RequestMapping(value="/saveitem", method = RequestMethod.POST)
public @ResponseBody Map<String, String> saveItem(@RequestBody ItemFormBean itemToEdit) {..}

经常出现的错误信息是:

客户端发送的请求语法错误(错误请求):Bad Request 400

为了弄清楚发生了什么,我不得不降低日志级别来发现问题,我发现:

调试 org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - 解决来自处理程序的异常 [public java.util.Map com.jarbits.quo.web.ItemController.saveItem(com.company.ItemFormBean,org .springframework.validation.BindingResult)]:org.springframework.http.converter.HttpMessageNotReadableException:无法读取 JSON:无法识别的字段“eItemId”(com.company.ItemFormBean 类),未标记为可忽略(6 个已知属性:“eitemId” , "eitemPartNbr", "eitemCode", "eforAnyCompany", "eitemDesc", "uomItemSlctId"])

映射Json对象的bean是:

@RooJavaBean
public class ItemFormBean {
    @NotNull
    private Long eItemId;
    @Size(min=3, max=30) 
    private String eItemCode;
    @Size(min=3, max=30)
    private String eItemPartNbr;
    @NotNull
    private String eItemDesc;
    @NotNull
    private Long uomItemSlctId;
    private boolean eForAnyCompany;
}

接下来的结果..


这里是结果.. 因此,基于 bean 定义的 Json 对象描述是正确的,但是控制器期望接收:

“eitemId”、“eitemPartNbr”、“eitemCode”、“eforAnyCompany”、“eitemDesc”、“uomItemSlctId”

代替:

“eItemId”、“eItemPartNbr”、“eItemCode”、“eForAnyCompany”、“eItemDesc”、“uomItemSlctId”

另外,我想提一下,我在 webmvc-config.xml 文件中有以下设置。

    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="false" />
    <property name="ignoreAcceptHeader" value="false" />
    <property name="mediaTypes" >
        <value>
            atom=application/atom+xml
            html=text/html
            json=application/json
            *=*/*
        </value>
    </property>
</bean>

这是因为 @ResponseBody 没有返回 json 对象结果。

@ Emrakul, @Humdinger 我对 Jackson 2.0 的降级进行了如下测试:

com.fasterxml.jackson.core
jackson-annotations 2.4.1 to 2.3.3
jackson-core 2.4.1.1 to 2.3.4
jackson-databind 2.4.1.3 to 2.3.4

我也有同样的缺陷。

正如你所说,这是杰克逊框架的一个缺陷。你能分享一下你的想法吗?

我希望这个缺陷可以对其他人有所帮助。

【问题讨论】:

  • 这很好,但是您可以做一些事情来改进它。自我回答问题时,请实际发布您的问题的答案,并附上其中的信息。然后,确保你的问题是独立的,并且本身看起来不错。这样,不认识你的人自己回答了这个问题,就会认为问题和答案都很好。感谢您传播您的知识!
  • 在我看来这实际上是一个缺陷。您是否尝试将 json 更改为小写的“坏”版本只是为了看看会发生什么?
  • 谢谢Emraku,下次我会做的。 Humdinger,我会试试的,我会及时通知你的。谢谢大家。
  • 你有getter和setter吗?

标签: java json spring spring-mvc


【解决方案1】:

我能够重现您的问题的唯一方法是使用

public class ItemFormBean {
    private String eItemCode;
    public String getEItemCode() {
        return eItemCode;
    }
    public void setEItemCode(String eItemCode) {
        this.eItemCode = eItemCode;
    }
}

{ ..., "eItemCode" : "asd", ... }

产生

Unrecognized field "eItemCode" (ItemFormBean) (6 known properties: ..., "eitemCode", ...])

默认情况下,Jackson 使用您的 getter 来确定属性名称。它通过去掉 getis 前缀并小写任何前导大写字符来实现这一点。

所以getEItemCode 将变成eitemCode。这就是它对 JSON 的期望。

如果需要,您可以通过使用 @JsonProperty("eItemCode") 注释 getter、setter 或字段之一来显式设置它。

【讨论】:

  • 谢谢@Sotirios Delimanolis,没错,但是缺陷是不常见的,常识说期望只是在“get”之后有第一个大写。 .我的意思是,getXzzzz,其中zzz可以是大写也可以是小写,Json应该遵循同样的意义。对,setter 和 getter 在 .aj 文件中,这是因为 Roo (@RooJavaBean) 框架维护。
【解决方案2】:

谢谢@Sotirios Delimanolis,没错,但是缺陷是不常见的,常识说期望只是在“get”之后拥有第一个大写......我的意思是,getXzzzz其中zzz可以是大写也可以是小写,Json应该遵循相同的含义。

对,setter 和 getter 在 .aj 文件中,这是因为 Roo (@RooJavaBean) 框架维护。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2013-12-30
    相关资源
    最近更新 更多