[英]How to deserialize Spring's ResponseEntity with Jackson ObjectMapper (probably with using @JsonCreator and Jackson mixins)
class ResponseEntity
doesn't have a default constructor 。 然后為了用 objectMapper 反序列化它,我決定使用 araqnid 在那個答案中給出的方法。 很快 - 它需要使用 Jackson 的混合特性和@JsonCreator。
在我的例子中(使用 ResponseEntity),由於不同的原因,它還沒有解決。
我的測試方法如下所示:
public static void main(String[] args) throws Exception {
ResponseEntity<Object> build = ResponseEntity.ok().build();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(ResponseEntity.class, ResponseEntityMixin.class);
String s = objectMapper.writeValueAsString(build);
ResponseEntity<Object> result = objectMapper.readValue(s, ResponseEntity.class);
System.out.println(result);
}
首先,我嘗試使用最短的 mixin 構造函數:
public abstract static class ResponseEntityMixin {
@JsonCreator
public ResponseEntityMixin(@JsonProperty("status") HttpStatus status) {
}
}
在這種情況下,我得到一個斷言錯誤,因為ResponseEntity
的構造函數中有這行代碼:
Assert.notNull(status, "HttpStatus must not be null");
然后我將 @JsonCreator 的模式切換為DELEGATING
但在這種情況下我得到了另一個異常:
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `org.springframework.http.HttpStatus` from String "headers": value not one of declared Enum instance names: [UPGRADE_REQUIRED, UNAVAILABLE_FOR_LEGAL_REASONS, SERVICE_UNAVAILABLE, CHECKPOINT, LOCKED, METHOD_FAILURE, FAILED_DEPENDENCY, UNPROCESSABLE_ENTITY, PROCESSING, PROXY_AUTHENTICATION_REQUIRED, METHOD_NOT_ALLOWED, GONE, MULTIPLE_CHOICES, GATEWAY_TIMEOUT, ACCEPTED, TEMPORARY_REDIRECT, INTERNAL_SERVER_ERROR, URI_TOO_LONG, LOOP_DETECTED, PAYLOAD_TOO_LARGE, EXPECTATION_FAILED, MOVED_TEMPORARILY, REQUEST_ENTITY_TOO_LARGE, NOT_EXTENDED, CREATED, RESET_CONTENT, BAD_GATEWAY, CONFLICT, VARIANT_ALSO_NEGOTIATES, NETWORK_AUTHENTICATION_REQUIRED, NOT_FOUND, LENGTH_REQUIRED, INSUFFICIENT_SPACE_ON_RESOURCE, NO_CONTENT, OK, FOUND, SEE_OTHER, BANDWIDTH_LIMIT_EXCEEDED, REQUEST_HEADER_FIELDS_TOO_LARGE, PERMANENT_REDIRECT, NOT_ACCEPTABLE, MOVED_PERMANENTLY, REQUEST_TIMEOUT, UNAUTHORIZED, USE_PROXY, IM_USED, ALREADY_REPORTED, PARTIAL_CONTENT, PRECONDITION_FAILED, REQUEST_URI_TOO_LONG, BAD_REQUEST, INSUFFICIENT_STORAGE, CONTINUE, NON_AUTHORITATIVE_INFORMATION, REQUESTED_RANGE_NOT_SATISFIABLE, UNSUPPORTED_MEDIA_TYPE, I_AM_A_TEAPOT, HTTP_VERSION_NOT_SUPPORTED, SWITCHING_PROTOCOLS, NOT_MODIFIED, NOT_IMPLEMENTED, TOO_MANY_REQUESTS, DESTINATION_LOCKED, PAYMENT_REQUIRED, FORBIDDEN, PRECONDITION_REQUIRED, MULTI_STATUS]
at [Source: (String)"{"headers":{},"body":null,"statusCode":"OK","statusCodeValue":200}"; line: 1, column: 2]
我還嘗試使用ResponseEntity
的全參數構造函數,但由於MultiValueMap
反序列化問題,它也沒有成功(但我相信,如果我修復它,它最終會給我帶來與上述相同的問題)。
誰能幫我解決這個問題? 也許在這種情況下根本不可能使用混合?
如果您知道另一種方法如何使用 Jackson 反序列化ResponseEntity
- 請也提供它們。
這是我測試的源代碼: https://github.com/amseager/responseentitydeserialization
使用MixIns
是一個很好的解決方法:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
public class Main {
public static void main(String[] args) throws Exception {
ResponseEntity<Object> entity = ResponseEntity
.ok()
.header("header", "value")
.body("Everything is OK!");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(ResponseEntity.class, ResponseEntityMixin.class);
objectMapper.addMixIn(HttpStatus.class, HttpStatusMixIn.class);
String json = objectMapper.writeValueAsString(entity);
TypeReference ref = new TypeReference<ResponseEntity<Object>>() {
};
ResponseEntity<Object> result = objectMapper.readValue(json, ref);
System.out.println(result);
System.out.println(result.equals(entity));
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
class ResponseEntityMixin {
@JsonCreator
public ResponseEntityMixin(@JsonProperty("body") Object body,
@JsonDeserialize(as = LinkedMultiValueMap.class) @JsonProperty("headers") MultiValueMap<String, String> headers,
@JsonProperty("statusCodeValue") HttpStatus status) {
}
}
class HttpStatusMixIn {
@JsonCreator
public static HttpStatus resolve(int statusCode) {
return HttpStatus.NO_CONTENT;
}
}
上面的代碼打印:
<200 OK OK,Everything is OK!,[header:"value"]>
和
true
這意味着源對象和反序列化對象是相同的。
您需要添加ResponseEntityDecoder
才能解析ResponseEntity
:
Feign.Builder builder = Feign.builder()
.encoder(new JacksonEncoder(objectMapper))
.decoder(new ResponseEntityDecoder(new JacksonDecoder(objectMapper)))
然后它應該工作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.