使用Ajax将对象传递给控制器​​ - 其中包含枚举

时间:2017-11-18 16:07:02

标签: ajax enums spring-data thymeleaf

我试图将对象Consumer传递给我的Controller。消费者与政策有一对多的关系。这就是我试过的:

function changeConsumer(){

  var newConsumer = {
            "id" : /*[[${consumer.id}]]*/,
            "name" : document.getElementById('0').value,
            "endpoint" : document.getElementById('1').value,
            "policies" : /*[[${policies}]]*/
    }

    $.ajax({
     type: "PUT",
     url: "/rest/consumer/update",
     data: JSON.stringify(newConsumer),
     contentType: "application/json; charset=utf-8",
     success : function(response) {
       ...
     });
   }

如果我像这样通过消费者,使用一系列空的策略 - 它可以工作:

function changeConsumer(){

      var newConsumer = {
                "id" : /*[[${consumer.id}]]*/,
                "name" : document.getElementById('0').value,
                "endpoint" : document.getElementById('1').value,
                "policies" : []
        }

        $.ajax({
         type: "PUT",
         url: "/rest/consumer/update",
         data: JSON.stringify(newConsumer),
         contentType: "application/json; charset=utf-8",
         success : function(response) {
           ...
         });
       }

这是我收到的堆栈跟踪,这让我觉得Enum"效果"在Policy对象中:

2017-11-18 16:28:22.255  WARN 7884 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of com.policyMgmt.policy.Effect out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@56bd85f4; line: 1, column: 93] (through reference chain: com.policyMgmt.consumer.Consumer["policies"]->java.util.ArrayList[0]->com.policyMgmt.policy.Policy["effect"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.policyMgmt.policy.Effect out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@56bd85f4; line: 1, column: 93] (through reference chain: com.policyMgmt.consumer.Consumer["policies"]->java.util.ArrayList[0]->com.policyMgmt.policy.Policy["effect"])
2017-11-18 16:28:22.255  WARN 7884 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of com.policyMgmt.policy.Effect out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@56bd85f4; line: 1, column: 93] (through reference chain: com.policyMgmt.consumer.Consumer["policies"]->java.util.ArrayList[0]->com.policyMgmt.policy.Policy["effect"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.policyMgmt.policy.Effekt out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@56bd85f4; line: 1, column: 93] (through reference chain: com.policyMgmt.consumer.Consumer["policies"]->java.util.ArrayList[0]->com.policyMgmt.policy.Policy["effect"])

Policy对象如下所示:

    @Entity
    public class Policy {
            @Id
            @GeneratedValue
            @Column(name = "id")
            private Integer id;

            @Column(name = "name")
            private String name;

            @Column (name = "consumer_id")
            private Integer consumer;

            @Enumerated(EnumType.STRING)
            @Column(name="effect")
            private Effect effect;

            public Policy() {}
    ....
}

也许有帮助,这就是消费者的样子:

@Entity
public class Consumer {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "endpoint")
    private String endpoint;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name ="consumer_id")
    private List<Policy> policies;


    public Consumer() {
    }
}

Rest API

@Controller
@RequestMapping(value = "/rest/consumer")
public class ConsumerController {
    ...
    @PutMapping(value = "/update")
    @ResponseBody
    public List<Consumer> updateConsumer(@RequestBody Consumer consumer) {}
...
}

有没有人有经验将Ajax中的枚举传递给Controller?

1 个答案:

答案 0 :(得分:0)

我无法确定为什么@RequestBody难以将{ "$type": "Effekt", "$name": "deny" }等JSON反序列化为Effekt枚举的实例,但我认为您应该尝试编写自定义你的枚举JsonDeserializer

此处another Stackoverflow question与您面临的问题相似但不完全相同。看一下第二个答案 - 包含JsonDeserializer的代码示例。

通过一些跟踪和错误,你可能会想出一些成功处理JSON的东西,就像你已经进入Effekt的实例一样。

另一个选项是更改发送到服务器的Effekt的JSON表示。也许如果它看起来像这样......

"effekt": "deny"

它可以直接与@RequestBody一起使用。您可以尝试在JavaScript中对其进行硬编码以进行测试。

如果你想走这条路,你可能需要实现一个自定义JsonSerializer - 与之前的选项相反。