업데이트 :이 모든 것을 작성한 후 분 (Jersey 2.13 사양의 제 12 장 선언 하이퍼 링크)이 발견되었습니다. 여전히 "개발 및 실험 중"이지만이 문제를 훨씬 더 우아하게 해결하는 것처럼 보입니다. 당신이 잭슨의 시리얼에 임의의 데이터를 보낼 필요가 다음 아래의 해결책은 여전히 유효하면 원래의 게시물의 모든 코드는
public class Pie {
private String name;
Pie(String name) {
this.name = name;
}
@JsonIgnore
public String getName() {
return name;
}
@InjectLink(value="pies/{name}", style=Style.ABSOLUTE)
public URI url;
}
...이 교체 할 수 있습니다.
ORIGINAL 나는 동일한 문제가있었습니다. 구체적으로는 리소스에 ID (URI 끝에있는 것) 만 포함하고 Jackson이 JSON을 생성 할 때만 UriInfo를 사용하여 전체 URI를 생성하는 방법을 찾고 싶습니다. 각 요청에 대해 내 리소스에 새로운 커버 객체를 만들거나 직렬화되기 전에 각 리소스에 UriInfo를 삽입해야하는 솔루션을 피하고자했습니다.
Jackson 2.3의 경우이 작업을 수행하는 아주 좋은 방법이 있습니다. Jackson은 ObjectWriterInjector라는 클래스를 지원합니다. 정적 세트 메서드를 사용하면 요청 당 한 번씩 ObjectWriterModifier의 고유 한 인스턴스를 제공 할 수 있습니다. 이 인스턴스는 UriInfo를 사용할 수있는 Jersey 리소스 메소드에서 생성하고 설정할 수 있습니다. Jackson은 JSON을 작성하기 전에 ObjectWriterModifier를 호출하여 사용할 ObjectWriter를 조정할 수있는 기회를 제공합니다. 이 경우 withAttribute 메서드를 사용하여 UriInfo를 ObjectWriter에 연결할 수 있습니다.
그래서 ObjectWriter의 속성은 무엇입니까? 이러한 특성은 JsonSerializer 구현의 serialize 메서드에서 SerializerProvider 매개 변수를 통해 사용할 수 있습니다. 제 경우에는 getter에서 @JsonSerialize를 사용하기 때문에 하나의 필드 만 수정하고 싶었습니다. serialize 메서드에서 SerializerProvider 매개 변수의 getAttribute 메서드를 호출하여 UriInfo를 검색 한 다음이를 사용하여 전체 URI를 생성합니다.
이 방법론은 정보를 Jackson serializer로 푸시하려는 경우에 유용합니다.
간단한 저지 자원 ...
@Path("/pies")
public class Pies {
static List<Pie> pies;
static
{
pies = new ArrayList<Pie>();
pies.add(new Pie("apple"));
pies.add(new Pie("pumpkin"));
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Pie> getPies(@Context UriInfo uriInfo) {
// This is the good stuff!!!!
ObjectWriterInjector.set(new ObjectWriterPlusUriInfo(uriInfo));
// Notice I don't have to anything to the objects in the Pies list
return pies;
}
}
ObjectWriter을 꼬집는 클래스 ...
class ObjectWriterPlusUriInfo extends ObjectWriterModifier {
private UriInfo uriInfo;
ObjectWriterPlusUriInfo(UriInfo uriInfo) {
this.uriInfo = uriInfo;
}
@Override
public ObjectWriter modify(EndpointConfigBase<?> endpoint,
MultivaluedMap<String, Object> responseHeaders, Object value,
ObjectWriter ow, JsonGenerator gen) throws IOException {
// Adding the UriInfo attribute
return ow.withAttribute("JerseyUriInfo", uriInfo);
}
}
잭슨 주석 파이 클래스
...
public class Pie {
private String name;
Pie(String name) {
this.name = name;
}
@JsonProperty(value="url")
@JsonSerialize(using=JacksonIdToUrlSerializer.class)
public String getName() {
return name;
}
}
시리얼 ...
public class JacksonIdToUrlSerializer extends JsonSerializer<String>{
@Override
public void serialize(String value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
UriInfo uriInfo = (UriInfo)provider.getAttribute("JerseyUriInfo");
jgen.writeString(uriInfo.getRequestUriBuilder().path(value).build().toString());
}
}
의 GET ...
http://localhost:8080/service/api/pies...
는 생산 .. .
http://127.0.0.1:8080/service/api/pies...
가 생산
363,210
[
{
url: "http://localhost:8080/service/api/pies/apple"
},
{
url: "http://localhost:8080/service/api/pies/pumpkin"
}
]
의 GET ... ObjectWriterInjector 그래서보다 일반적인 방법은 아래의 데이터를 전달하는 것을 이용한 내부 스레드 로컬 변수를 사용
[
{
url: "http://127.0.0.1:8080/service/api/pies/apple"
},
{
url: "http://127.0.0.1:8080/service/api/pies/pumpkin"
}
]
참고 요청 당 기준은 똑같이 유효합니다.
은 MessageBodyWriter가 아닌 잭슨이 무엇입니까? 모든 객체의 모든 부분을 직렬화하는 손이 불편하고 오류가 발생하기 쉽습니다. 엔티티에 삽입 할 수 없기 때문에 도움이되지 않는 CDI 빈이라 할지라도 jax-rs 레벨 솔루션이 있는지 확신하지 못합니다 ... – xenoterracide