【发布时间】:2018-08-16 16:18:49
【问题描述】:
我是 Spring Actuator 2 的新手,即将放弃如何以 JSON {"fruit": {"id": 1, "name": "apple"}} 对 http://localhost:8080/actuator/fruits 的形式 HTTP-POST 实体,因为它拒绝了我的错误请求:
JSON parse error: Cannot deserialize instance of 'java.lang.String' out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of 'java.lang.String' out of START_OBJECT token\n at [Source: (PushbackInputStream); line: 1, column: 11] (through reference chain: java.util.LinkedHashMap[\"fruit\"])
如果我发布{"fruit": "{\"id\": 1, \"name\": \"apple\"}"},我也会收到带有Parameter mapping failure 的错误请求(当然,因为我的端点方法参数的类型是Fruit 而不是String)。
到目前为止,我发现的原因是,Jackson 期望 java.util.Map<String, String> 最终由 org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler#handle(javax.servlet.http.HttpServletRequest, Map<String, String>) 告知(通过一些反思)(第二个参数是罪魁祸首)。
我的问题是:有没有一种巧妙的方法可以让我的 HTTP-POST 端点接受 Fruit(不接受 String 并明确解析它)?
附录
我的水果类(Kotlin):
data class Fruit(val id: Long, val name: String)
我的 Fruits 类(翻译成 Java):
public final class Fruit {
private final Long id;
private final String name;
public Fruit(Long id, String name) {
this.id = id;
this.name = name;
}
public final Long getId() { return id; }
public final String getName() { return name; }
}
我的端点类:
@org.springframework.stereotype.Component
@org.springframework.boot.actuate.endpoint.annotation.Endpoint(id = "fruits")
class FruitsEndpoint() {
@org.springframework.boot.actuate.endpoint.annotation.WriteOperation
fun addFruit(fruit: Fruit) { println(fruit) }
}
我的 Endpoint 类(翻译成 Java):
@org.springframework.stereotype.Component
@org.springframework.boot.actuate.endpoint.annotation.Endpoint(id = "fruits")
public final class FruitsEndpoint {
@org.springframework.boot.actuate.endpoint.annotation.WriteOperation
public void addFruit(Fruit fruit) { System.out.println(fruit); }
}
【问题讨论】:
标签: java spring spring-boot kotlin spring-boot-actuator