JSON Jackson에 대한 날짜 형식 매핑
API에서 제공되는 Date 포맷은 다음과 같습니다.
"start_time": "2015-10-1 3:00 PM GMT+1:00"
YYY-DD-MM HH는 무엇입니까?MM am/pm GMT 타임스탬프이 값을 POJO의 날짜 변수에 매핑합니다.분명히 변환 오류를 나타내고 있습니다.
다음 두 가지를 알고 싶습니다.
- 잭슨과의 변환에 필요한 포맷은 무엇입니까?이 경우 Date가 적합한 필드 유형입니까?
- 일반적으로 변수가 잭슨에 의해 오브젝트 멤버에게 매핑되기 전에 처리할 수 있는 방법이 있습니까?예를 들어 형식 변경, 계산 등.
Jackson v2.0 이후 오브젝트 멤버에게 직접 @JsonFormat 주석을 사용할 수 있습니다.
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm a z")
private Date date;
잭슨과의 변환에 필요한 포맷은 무엇입니까?이 경우 Date가 적합한 필드 유형입니까?
Date
이 경우 적합한 필드 유형입니다.은 JSON을 할 수 .ObjectMapper.setDateFormat
:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
myObjectMapper.setDateFormat(df);
일반적으로 변수가 잭슨에 의해 오브젝트 멤버에게 매핑되기 전에 처리할 수 있는 방법이 있습니까?예를 들어 형식 변경, 계산 등.
네의 몇 옵션이 . 이데올로기 때문에JsonDeserializer
)JsonDeserializer<Date>
시작이 좋다.
물론 serialization과 deserialization이라고 하는 자동화된 방법이 있으며 pb2q에서 설명한 바와 같이 특정 주석(@JsonSerialize,@JsonDeserialize)으로 정의할 수도 있습니다.
두 java.util을 모두 사용할 수 있습니다.날짜 및 java.util.달력... 그리고 아마 Joda Time도 있을 거예요.
@JsonFormat 주석이 역직렬화(시리얼라이제이션이 완벽하게 작동) 중에 원하는 대로 작동하지 않았습니다(타임존을 다른 값으로 조정했습니다).
@JsonFormat(locale = "hu", shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "CET")
@JsonFormat(locale = "hu", shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Europe/Budapest")
예측 결과를 원하는 경우 @JsonFormat 주석 대신 커스텀시리얼라이저와 커스텀디시리얼라이저를 사용해야 합니다.http://www.baeldung.com/jackson-serialize-dates에서 정말 좋은 튜토리얼과 솔루션을 찾았습니다.
날짜 필드에는 예가 있지만 캘린더 필드에는 필요하기 때문에 구현은 다음과 같습니다.
시리얼라이저 클래스:
public class CustomCalendarSerializer extends JsonSerializer<Calendar> {
public static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
public static final Locale LOCALE_HUNGARIAN = new Locale("hu", "HU");
public static final TimeZone LOCAL_TIME_ZONE = TimeZone.getTimeZone("Europe/Budapest");
@Override
public void serialize(Calendar value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
if (value == null) {
gen.writeNull();
} else {
gen.writeString(FORMATTER.format(value.getTime()));
}
}
}
디시리얼라이저 클래스:
public class CustomCalendarDeserializer extends JsonDeserializer<Calendar> {
@Override
public Calendar deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException {
String dateAsString = jsonparser.getText();
try {
Date date = CustomCalendarSerializer.FORMATTER.parse(dateAsString);
Calendar calendar = Calendar.getInstance(
CustomCalendarSerializer.LOCAL_TIME_ZONE,
CustomCalendarSerializer.LOCALE_HUNGARIAN
);
calendar.setTime(date);
return calendar;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
및 상기 클래스의 사용방법:
public class CalendarEntry {
@JsonSerialize(using = CustomCalendarSerializer.class)
@JsonDeserialize(using = CustomCalendarDeserializer.class)
private Calendar calendar;
// ... additional things ...
}
이 실장을 사용하면, 시리얼라이제이션 및 역시리얼라이제이션프로세스가 연속적으로 실행되어 원래의 값이 됩니다.
@JsonFormat 주석만 사용하면 라이브러리 내부 시간대의 기본 설정 때문에 주석 매개 변수로는 변경할 수 없는 다른 결과를 얻을 수 있습니다(그것이 잭슨 라이브러리 2.5.3 및 2.6.3 버전 사용 경험이기도 합니다).
날짜에 T 및 Z와 같은 문자를 추가하려면
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private Date currentTime;
산출량
{
"currentTime": "2019-12-11T11:40:49Z"
}
이 예에서는 를 사용한Spring Boot 어플리케이션의 완전한 예를 나타냅니다.RFC3339
datetime 형식
package bj.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import java.text.SimpleDateFormat;
/**
* Created by BaiJiFeiLong@gmail.com at 2018/5/4 10:22
*/
@SpringBootApplication
public class BarApp implements ApplicationListener<ApplicationReadyEvent> {
public static void main(String[] args) {
SpringApplication.run(BarApp.class, args);
}
@Autowired
private ObjectMapper objectMapper;
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));
}
}
@miklov-kriven의 매우 도움이 되는 답변을 바탕으로, 저는 이 두 가지 추가 고려 사항이 누군가에게 도움이 되기를 바랍니다.
(1) 시리얼라이저와 디시리얼라이저를 같은 클래스에 스태틱한 내부 클래스로 포함시키는 것이 좋습니다.NB, SimpleDateFormat의 스레드 안전을 위해 ThreadLocal을 사용합니다.
public class DateConverter {
private static final ThreadLocal<SimpleDateFormat> sdf =
ThreadLocal.<SimpleDateFormat>withInitial(
() -> {return new SimpleDateFormat("yyyy-MM-dd HH:mm a z");});
public static class Serialize extends JsonSerializer<Date> {
@Override
public void serialize(Date value, JsonGenerator jgen SerializerProvider provider) throws Exception {
if (value == null) {
jgen.writeNull();
}
else {
jgen.writeString(sdf.get().format(value));
}
}
}
public static class Deserialize extends JsonDeserializer<Date> {
@Overrride
public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws Exception {
String dateAsString = jp.getText();
try {
if (Strings.isNullOrEmpty(dateAsString)) {
return null;
}
else {
return new Date(sdf.get().parse(dateAsString).getTime());
}
}
catch (ParseException pe) {
throw new RuntimeException(pe);
}
}
}
}
(2) 각 클래스 멤버에서 @JsonSerialize 및 @JsonDeserialize 주석을 사용하는 대신 어플리케이션레벨에서 커스텀시리얼라이즈를 적용하여 잭슨의 디폴트시리얼라이즈를 덮어쓰는 것도 고려할 수 있습니다.즉, Date 타입의 모든 클래스멤버는 이 커스텀시리얼라이제이션 없이 이 커스텀시리얼라이즈를 사용하여 잭슨에 의해 시리얼라이즈 됩니다.각 필드에 xplicit 주석이 표시됩니다.예를 들어 Spring Boot를 사용하는 경우 다음과 같은 방법이 있습니다.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public Module customModule() {
SimpleModule module = new SimpleModule();
module.addSerializer(Date.class, new DateConverter.Serialize());
module.addDeserializer(Date.class, new Dateconverter.Deserialize());
return module;
}
}
날 위해 일하는 거지Spring Boot.
import com.alibaba.fastjson.annotation.JSONField;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
출력:
{
"createTime": "2019-06-14 13:07:21"
}
java.sql에 대한 사용자 정의 날짜 형식을 사용하는 데 문제가 있는 경우.날짜, 이것이 가장 간단한 해결책입니다.
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(java.sql.Date.class, new DateSerializer());
mapper.registerModule(module);
(이 SO 답변으로 많은 수고를 덜 수 있었습니다.https://stackoverflow.com/a/35212795/3149048 )
Jackson은 기본적으로 java.sql에 SqlDateSerializer를 사용합니다.날짜. 단, 현재 이 시리얼라이저에서는 날짜 형식은 고려되지 않습니다.이 문제를 참조해 주세요.https://github.com/FasterXML/jackson-databind/issues/1407회피책은 java.sql에 다른 시리얼라이저를 등록하는 것입니다.코드 예시와 같은 날짜입니다.
이 설정을 지적하고 싶습니다.SimpleDateFormat
다른 답변에서 설명한 바와 같이 동작하는 것은java.util.Date
내 생각엔 그건 질문에서 의도된 것 같아.하지만 을 위해서java.sql.Date
포메터가 작동하지 않습니다.제 경우 포맷터가 작동하지 않는 이유는 명확하지 않았습니다. 왜냐하면 직렬화되어야 할 모델에서 필드는 실제로 a였습니다.java.utl.Date
하지만 실제 물체는 결국 비명을 지르고 말았다.java.sql.Date
이 한 이유는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★
public class java.sql extends java.util.Date
그래서 이것은 실제로 유효하다.
java.util.Date date = new java.sql.Date(1542381115815L);
[] 의 형식이 않은 [Date]인지 합니다.java.util.Date
.
여기에서는, 취급의 이유에 대해서도 언급하고 있습니다.java.sql.Date
추가되지 않습니다.
이것은 변화를 깨는 것이 될 것이고, 나는 그것이 정당화될 수 있다고 생각하지 않는다.만약 우리가 처음부터 시작한다면 나는 그 변화에 동의하겠지만, 상황이 그렇게 심각하지는 않다.
언급URL : https://stackoverflow.com/questions/12463049/date-format-mapping-to-json-jackson
'itsource' 카테고리의 다른 글
Angular JS를 사용하여 부트스트랩 네비게이션바의 액티브클래스를 설정하려면 어떻게 해야 하나요? (0) | 2022.12.04 |
---|---|
Image Magick 설치 확인 (0) | 2022.12.04 |
특성 함수를 재정의하고 재정의된 함수에서 호출하려면 어떻게 해야 합니까? (0) | 2022.12.04 |
유닛 테스트를 PHP로 작성하려면 어떻게 해야 하나요? (0) | 2022.12.04 |
검색되지 않은(약속되지 않은) 탐색 잘못된 자격 증명에서 중복된 오류 발생 (0) | 2022.12.04 |