API 버전에 따라 정확한 속성 이름을 추출하기 위해 JacksonAnnotationIntrospector를 사용하여 사용자 정의 주석을 설정했습니다. API 버전에 따라 올바른 ObjectMapper를 내보내는 도우미 클래스가 있습니다.응답을 보낼 때 MessageBodyWriter가 사용되지 않습니다.
public class ObjectMapperFactory {
private static final ObjectMapper objectMapper_V1 = new ObjectMapper().setAnnotationIntrospector(new VersioningPropertiesIntrospector(Entity.ApiVersion.V1));
private static final ObjectMapper objectMapper_V2016 = new ObjectMapper().setAnnotationIntrospector(new VersioningPropertiesIntrospector(Entity.ApiVersion.V2016));
public static ObjectMapper getObjectMapper(Entity.ApiVersion version) {
switch (version) {
case V1:
return objectMapper_V1;
case V2016:
return objectMapper_V2016;
case INVALID:
return null;
}
return null;
}
}
이 같은 단위 테스트에 직렬화
public static String serializeEntity(Entity.ApiVersion version, Object object) {
try {
return getObjectMapper(version).writeValueAsString(object);
} catch (JsonProcessingException e) {
log.error(e.toString());
}
return "Invalid API version.";
}
을 테스트하는 데 사용하는 도우미 기능이있다 :
: 이제@Test
public void testSerializeUserWithStateField() {
User user = new User();
user.setVersion(Entity.ApiVersion.V2016);
user.setState(EntityState.CREATED.name());
String userJson = serializeEntity(user.getVersion(), user);
assertThat(userJson, equalTo("{\"lifecycleState\":\"CREATED\"}"));
}
, 나는 이런 식으로 뭔가가 있다고
@GET
@Path("users/{userId}")
public Response getUser(@PrincipalContext Principal principal,
@AuthorizationRequestContext AuthorizationRequest authorizationRequest,
@PathParam("userId") String userId) {
final String decodedId = Optional
.ofNullable(RequestValidationHelper.decodeUrlEncodedOCID(userId))
.filter(StringUtils::isNotEmpty)
.orElseThrow(BadArgumentException::new);
User user = userStore.getUser(decodedId)
.orElseThrow(OperationNotAllowedException::new);
log.debug("Successfully retrieved user '{}'", decodedId);
return Response.status(Response.Status.OK)
.header(HttpHeaders.ETAG, user.getEtag())
.entity(user)
.build();
}
사용자가 엔터티를 확장합니다.
public abstract class Entity {
private String id;
private String userId;
@JsonIgnore
private String etag;
@VersioningProperties({
@VersioningProperties.Property(version = ApiVersion.V1, value = "state"),
@VersioningProperties.Property(version = ApiVersion.V2016, value = "lifecycleState")
})
private String state;
@JsonIgnore
private ApiVersion version = ApiVersion.INVALID;
public enum ApiVersion {
INVALID,
V1,
V2016
}
}
나는 올바른 JSON을 반환한다는 것을 알고 있습니다. 응답을 생성 할 때 .entity()에서 serializeEntity에 대한 호출을 삽입 할 수는 있지만 응답의 엔터티가 동일한 유형 (예 : User)인지 확인하는 테스트에서 문제가 발생했습니다. 단일 객체의 직렬화 된 버전이나 일련 번호가 지정된 List <>의 문자열을 찾은 경우 (예 : 어떤 경우이든) 객체가 발견됩니다.
올바르게 이해한다면 @Provider 주석을 사용하여 MessageBodyWriter를 지정하면 지정된 객체를 직렬화 할 때 (즉, Dropwizard와 Jersey를 사용할 때) @Provider 주석을 지정해야합니다.
@Provider
public class EntityMessageBodyWriter implements MessageBodyWriter<Entity> {
@Override
public long getSize(Entity entity, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return 0;
}
@Override
public boolean isWriteable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return Entity.class.isAssignableFrom(aClass);
}
@Override
public void writeTo(Entity entity, Class<?> aClass, Type type, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> multivaluedMap, OutputStream outputStream)
throws IOException, WebApplicationException {
outputStream.write(serializeEntity(entity.getVersion(), entity).getBytes());
}
}
그러나 그런 경우는 아닙니다. 나는 모든 객체에 대해 별도의 MessageBodyWriter를 만들지 않았다. 문서에서 여러분은 수퍼 클래스를 사용할 수 있다고 말했고, 모든 하위 클래스 또한 일치 할 것이다. (내가했던 isWriteable() 함수에서 true를 반환한다고 가정). 또한 JSON 미디어 유형으로 @Produces를 지정하고 Entity 대신 User와 같은 하위 클래스 하나만 지정하는 등의 작업을 시도했지만 아무 것도 작동하지 않는 것 같습니다.
은 또한으로 MessageBodyWriter 등록 시도 :
JerseyEnvironment jersey = env.jersey();
jersey.register(new IdentityEntityMessageBodyWriter());
하지만 한 모든 것을 우리가 (500S, 409s 등)이 거의 모든 시험을 중단했다.
API 버전 인 state
을 기반으로 변경하려는 변수가 V2016 API 호출에 대한 응답으로 lifecycleState
으로 설정되지 않습니다. 어떻게하면 제대로 작동합니까?
안녕하세요, 귀하의 질문에 예외가 추가 될 수 있습니까? – pandaadb
예외가 실제로 throw되지 않습니다. 컴파일되고 실행되지만 속성 이름의 잘못된 버전이 튀어 나옵니다. – Gemini14
메시지 작성자가 불렀습니까? serializeEntity에 중단 점을 설정할 때 무슨 일이 일어나고 있습니까? 이 문제는 프로덕션 문제입니까 (예 : 서버를 실행할 때 실패하는 것으로 보입니까) 아니면 통합 테스트 문제입니까? – pandaadb