특정 필드에 대한 Jackson JSON 사용자 지정 일련화
Jackson JSON 프로세서를 사용하여 커스텀 필드 레벨의 시리얼화를 실시하는 방법이 있습니까?예를 들어, 나는 수업을 하고 싶다.
public class Person {
public String name;
public int age;
public int favoriteNumber;
}
다음 JSON으로 시리얼화 됩니다.
{ "name": "Joe", "age": 25, "favoriteNumber": "123" }
age=25는 숫자로 인코딩되고 favoriteNumber=123은 문자열로 인코딩됩니다.잭슨 마샬은 개봉 후int
몇 개로 줄여서.이 경우 favorite Number를 문자열로 인코딩합니다.
다음과 같이 커스텀시리얼라이저를 실장할 수 있습니다.
public class Person {
public String name;
public int age;
@JsonSerialize(using = IntToStringSerializer.class, as=String.class)
public int favoriteNumber:
}
public class IntToStringSerializer extends JsonSerializer<Integer> {
@Override
public void serialize(Integer tmpInt,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider)
throws IOException, JsonProcessingException {
jsonGenerator.writeObject(tmpInt.toString());
}
}
Java는 다음 위치에서 자동 박스를 처리합니다.int
로.Integer
널 위해서.
Jackson-databind(최소 2.1.3)는 특별한 기능을 제공합니다.ToStringSerializer
(com.fasterxml.jackson.databind.ser.std.ToStringSerializer
)
예를 들어:
public class Person {
public String name;
public int age;
@JsonSerialize(using = ToStringSerializer.class)
public int favoriteNumber:
}
를 추가합니다.@JsonProperty
주석이 달린 getter를 반환한다.String
,를 위해favoriteNumber
필드:
public class Person {
public String name;
public int age;
private int favoriteNumber;
public Person(String name, int age, int favoriteNumber) {
this.name = name;
this.age = age;
this.favoriteNumber = favoriteNumber;
}
@JsonProperty
public String getFavoriteNumber() {
return String.valueOf(favoriteNumber);
}
public static void main(String... args) throws Exception {
Person p = new Person("Joe", 25, 123);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(p));
// {"name":"Joe","age":25,"favoriteNumber":"123"}
}
}
Jackson이 제공하는 정보@JsonFormat
커스텀 시리얼라이저를 쓸 필요 없이 많은 커스터마이즈를 처리할 수 있습니다.
예를 들어, 요구는STRING
숫자 유형이 있는 필드의 모양은 숫자 값을 문자열로 출력합니다.
public class Person {
public String name;
public int age;
@JsonFormat(shape = JsonFormat.Shape.STRING)
public int favoriteNumber;
}
원하는 출력을 얻을 수 있습니다.
{"name":"Joe","age":25,"favoriteNumber":"123"}
주석을 사용하여 모형을 오염시키지 않고 사용자 지정 작업을 수행하려는 경우 혼합을 사용할 수 있습니다.
ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.setMixInAnnotation(Person.class, PersonMixin.class);
mapper.registerModule(simpleModule);
재지정 기간:
public abstract class PersonMixin {
@JsonSerialize(using = PersonAgeSerializer.class)
public String age;
}
연령에 따라 필요한 모든 것을 할 수 있습니다.
public class PersonAgeSerializer extends JsonSerializer<Integer> {
@Override
public void serialize(Integer integer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(String.valueOf(integer * 52) + " months");
}
}
@JsonView의 도움을 받아 최소 기준을 충족하는 모델 클래스의 필드를 시리얼화할 수 있습니다.예를 들어 10개의 속성을 가진 코어 클래스는 1개이지만 클라이언트에 필요한 속성은 5개뿐입니다.
다음 클래스를 만드는 것만으로 뷰를 정의할 수 있습니다.
public class Views
{
static class Android{};
static class IOS{};
static class Web{};
}
뷰가 있는 주석 모델 클래스:
public class Demo
{
public Demo()
{
}
@JsonView(Views.IOS.class)
private String iosField;
@JsonView(Views.Android.class)
private String androidField;
@JsonView(Views.Web.class)
private String webField;
// getters/setters
...
..
}
이제 봄부터 HttpMessageConverter 클래스를 다음과 같이 확장하여 커스텀 json 컨버터를 작성해야 합니다.
public class CustomJacksonConverter implements HttpMessageConverter<Object>
{
public CustomJacksonConverter()
{
super();
//this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.ClientView.class));
this.delegate.getObjectMapper().configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
this.delegate.getObjectMapper().setSerializationInclusion(Include.NON_NULL);
}
// a real message converter that will respond to methods and do the actual work
private MappingJackson2HttpMessageConverter delegate = new MappingJackson2HttpMessageConverter();
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return delegate.canRead(clazz, mediaType);
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return delegate.canWrite(clazz, mediaType);
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return delegate.getSupportedMediaTypes();
}
@Override
public Object read(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException,
HttpMessageNotReadableException {
return delegate.read(clazz, inputMessage);
}
@Override
public void write(Object obj, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException
{
synchronized(this)
{
String userAgent = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("userAgent");
if ( userAgent != null )
{
switch (userAgent)
{
case "IOS" :
this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.IOS.class));
break;
case "Android" :
this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.Android.class));
break;
case "Web" :
this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( Views.Web.class));
break;
default:
this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( null ));
break;
}
}
else
{
// reset to default view
this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( null ));
}
delegate.write(obj, contentType, outputMessage);
}
}
}
이 커스텀 json 변환을 사용하기 위해서는 단순히 dispatcher-servlet.xml에 넣기만 하면 됩니다.
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean id="jsonConverter" class="com.mactores.org.CustomJacksonConverter" >
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
그래야 시리얼화할 필드를 결정할 수 있습니다.
믹스인으로 커스텀시리얼라이저를 인라인으로 작성할 수 있습니다.그런 다음 필드에 주석을 추가합니다.lang 필드에 " - something other " 필드를 추가하는 예는 다음과 같습니다.이것은 좀 해커가 됩니다.시리얼라이저가 저장소나 봄까지 주입된 것을 필요로 한다면, 이것은 문제가 될 것입니다.믹스인 대신 커스텀 디시리얼라이저/시리얼라이저를 사용하는 것이 좋습니다.
package com.test;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.test.Argument;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//Serialize only fields explicitly mentioned by this mixin.
@JsonAutoDetect(
fieldVisibility = Visibility.NONE,
setterVisibility = Visibility.NONE,
getterVisibility = Visibility.NONE,
isGetterVisibility = Visibility.NONE,
creatorVisibility = Visibility.NONE
)
@JsonPropertyOrder({"lang", "name", "value"})
public abstract class V2ArgumentMixin {
@JsonProperty("name")
private String name;
@JsonSerialize(using = LangCustomSerializer.class, as=String.class)
@JsonProperty("lang")
private String lang;
@JsonProperty("value")
private Object value;
public static class LangCustomSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider)
throws IOException, JsonProcessingException {
jsonGenerator.writeObject(value.toString() + " - something else");
}
}
}
언급URL : https://stackoverflow.com/questions/12046786/jackson-json-custom-serialization-for-certain-fields
'programing' 카테고리의 다른 글
Kubernetes의 Mariadb 통신 패킷을 읽는 동안 오류가 발생했습니다. (0) | 2023.01.13 |
---|---|
인증 플러그인 'caching_sha2_password' 문제를 해결하는 방법 (0) | 2023.01.13 |
nuxtServerInit은 네비게이션이 발생할 때마다 실행됩니다. (0) | 2023.01.03 |
PHP: $_SESS 내에 '개체' 저장이온 (0) | 2023.01.03 |
phpMyAdmin의 MySQL 로그는 어디서 찾을 수 있습니까? (0) | 2023.01.03 |