我有一个POJO课程
public class Stock{
int id;
String name;
Date date;
}
Run Code Online (Sandbox Code Playgroud)
是否有任何注释或开发框架/ api可以将POJO转换为JSON模式,如下所示
{"id":
{
"type" : "int"
},
"name":{
"type" : "string"
}
"date":{
"type" : "Date"
}
}
Run Code Online (Sandbox Code Playgroud)
并且我可以通过在POJO上指定一些注释或配置来扩展模式以添加诸如"必需"之类的信息:"是",每个字段的描述等,并且可以生成如下的JSON模式.
{"id":
{
"type" : "int",
"Required" : "Yes",
"format" : "id must not be greater than 99999",
"description" : "id of the stock"
},
"name":{
"type" : "string",
"Required" : "Yes",
"format" : "name must not be empty and must be 15-30 characters length",
"description" : "name of the …Run Code Online (Sandbox Code Playgroud) 我正在为新的JDK8 java.time类寻找一个模块.我查看了FasterXML GitHub项目列表,目前没有找到.
据我所知,Jackson仍然是针对JDK6编译的,所以不能直接使用这些类,并且必须将它构建为一个单独的模块,正如Joda所要求的那样.
我不介意启动这个项目,但是看看是否还有其他工作正在进行中.
我已经在我的项目中使用了FasterXML/Jackson-Databind一段时间,并且一切都很好,直到我发现这篇文章并开始使用这种方法来反序列化没有@JsonProperty注释的对象.
问题是,当我有一个构造函数接受多个参数并使用@JsonCreator注释装饰这个构造函数时,Jackson会抛出以下错误:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:
Argument #0 of constructor [constructor for com.eliti.model.Cruiser, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at [Source: {
"class" : "com.eliti.model.Cruiser",
"inventor" : "afoaisf",
"type" : "MeansTransport",
"capacity" : 123,
"maxSpeed" : 100
}; line: 1, column: 1]
Run Code Online (Sandbox Code Playgroud)
我已经创建了一个小项目来说明问题,我试图反序列化的类是这个:
public class Cruise extends WaterVehicle {
private Integer maxSpeed;
@JsonCreator
public Cruise(String name, Integer maxSpeed) {
super(name);
System.out.println("Cruise.Cruise");
this.maxSpeed = maxSpeed; …Run Code Online (Sandbox Code Playgroud) 是)我有的:
我正在从pojo生成JSON模式.我生成模式的代码如下所示:
ObjectMapper mapper = new ObjectMapper();
TitleSchemaFactoryWrapper visitor = new TitleSchemaFactoryWrapper();
mapper.acceptJsonFormatVisitor(clazz, visitor);
JsonSchema schema = visitor.finalSchema();
schemas.put(clazz, mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));
Run Code Online (Sandbox Code Playgroud)
我通过上面的代码生成了几个模式.其中一个pojos有一个内部嵌入枚举来限制可能的值,如下所示:
public class MyClass {
@JsonProperty("name")
private String name;
@JsonProperty("startDayOfWeek")
private MyClass.StartDayOfWeek startDayOfWeek;
/**
* The ID of a timezone returned by the timezones route.
*
*/
@JsonProperty("timezone")
private String timezone;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* @return
* The startDayOfWeek
*/
@JsonProperty("startDayOfWeek")
public MyClass.StartDayOfWeek getStartDayOfWeek() {
return startDayOfWeek;
}
/**
*
* @param …Run Code Online (Sandbox Code Playgroud) 方案如下.我有一个ObjectMapper(Jackson 2),它注册了一个JodaModule,能够序列化和反序列化Joda DateTime类型.此ObjectMapper使用自定义JSON字符串进行测试,并按预期工作.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JodaModule());
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+1:00"));
objectMapper.setDateFormat(new ISO8601DateFormat());
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
Run Code Online (Sandbox Code Playgroud)
我有一个RestTemplateFactory负责实例化RestTemplate,它将以前配置的ObjectMapper bean设置为RestTemplate.
@Configuration
public class RestTemplateFactory {
@Autowired
private ObjectMapper objectMapper;
@Bean
public RestTemplate createRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
jsonMessageConverter.setObjectMapper(objectMapper);
messageConverters.add(jsonMessageConverter);
// restTemplate.setMessageConverters(messageConverters); // This line was missing, but needs to be here. See answer.
return restTemplate;
}
}
Run Code Online (Sandbox Code Playgroud)
现在当我联系webservice时,它无法使用以下错误消息反序列化DateTime对象:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not instantiate value …Run Code Online (Sandbox Code Playgroud) 我正在使用Jackson 2.8并且需要与ISO 8601时间戳内不允许毫秒的API进行通信.
预期的格式是这样的: "2016-12-24T00:00:00Z"
我正在使用Jackson的JavaTimeModule WRITE_DATES_AS_TIMESTAMPS设置为false.
但这将打印毫秒.
所以我尝试使用objectMapper.setDateFormat哪个没有改变任何东西.
我目前的解决方法是:
ObjectMapper om = new ObjectMapper();
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendInstant(0)
.toFormatter();
JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class, new JsonSerializer<Instant>() {
@Override
public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeString(dtf.format(value));
}
});
om.registerModule(jtm);
Run Code Online (Sandbox Code Playgroud)
我正在覆盖默认的序列化工具Instant.class.
有没有什么好办法使用一些配置参数来解决这个问题?
是否可以使用Jackson设置Jersey以使用多个配置进行序列化/反序列化ObjectMappers?
我希望能够做的是注册一个"默认"杰克逊ObjectMapper,然后能够注册另一个功能,提供ObjectMapper一些特殊配置,在某些情况下将"覆盖""默认" ObjectMapper.
例如,这ContextResolver将是"默认"映射器:
@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class JacksonMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mObjectMapper;
public JacksonMapperProvider() {
mObjectMapper = createMapper();
}
protected abstract ObjectMapper createMapper() {
ObjectMapper mapper = createMapper();
return mapper
.setSerializationInclusion(Include.ALWAYS)
.configure(JsonParser.Feature.ALLOW_COMMENTS, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mObjectMapper;
}
}
Run Code Online (Sandbox Code Playgroud)
这ContextResolver将覆盖"默认"映射器:
@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class SpecializedMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mObjectMapper; …Run Code Online (Sandbox Code Playgroud) 我有一个实体:
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String title;
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个控制器,其目的是检索书籍,我的问题是,类型字段被包含在我的控制器的json响应中.任何方式我可以排除那些杰克逊序列化对象时延迟加载的字段?
这是我的ObjectMapper的配置:
Hibernate4Module hm = new Hibernate4Module();
hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false);
registerModule(hm);
configure(SerializationFeature.INDENT_OUTPUT, true);
Run Code Online (Sandbox Code Playgroud)
谢谢!
我无法将其标记为JsonIgnore,因为它将永远不在序列化框中.有时候我需要随书检索这些类型,然后我会在查询中使用"fetch join",这样它就不会为空.
我一直在尝试升级JSON模块以使用Jackson的FasterXML(2.6.3)版本而不是旧的Codehaus模块.在升级过程中,我注意到使用FasterXML而不是Codehaus时命名策略有所不同.
Codehaus在命名策略方面更灵活.下面的测试突出了我用FasterXML面临的问题.我如何配置ObjectMapper它遵循Codehaus相同的策略?
我不能改变JSONProperty注释,因为有数百个注释.我希望升级在命名策略方面向后兼容.
import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
/*import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.PropertyNamingStrategy;*/
import org.junit.Assert;
import org.junit.Test;
public class JSONTest extends Assert {
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Product {
@JsonProperty(value = "variationId")
private String variantId;
@JsonProperty(value = "price_text")
private String priceText;
@JsonProperty(value = "listPrice")
public String listPrice;
@JsonProperty(value = "PRODUCT_NAME")
public String name;
@JsonProperty(value = "Product_Desc")
public String description;
}
private static final String VALID_PRODUCT_JSON = …Run Code Online (Sandbox Code Playgroud) 我在发布之前搜索过Stack Overflow,但杰克逊没有解决方案.
这是服务器响应:
{
"ok": true,
"result": [
{
"update_id": 489881731,
//rest
},
{
"update_id": 489881732,
//rest
}
]
}
Run Code Online (Sandbox Code Playgroud)
如您所见,属性"result"是一个数组.
现在这是另一个回应:
{
"ok": true,
"result": {
"id": 211948704,
"first_name": "???? ????????? ??????",
"username": "tgAdminsBot"
}
}
Run Code Online (Sandbox Code Playgroud)
这"result"是一个单一的对象.
这是我的课程,我想将内容反序列化.我写了一个自定义解串器的TObject课程:
public class Result
{
private TObject[] result;
private boolean ok;
public void setOk (boolean ok) {//code}
public void setResult (TObject[] result) {//code}
public TObject[] getResult () {//code}
public boolean getOk (){//code}
}
Run Code Online (Sandbox Code Playgroud)
所以,我认为在我的课是" …