【问题标题】:How to serialize declarative links (jersey) with jackson如何用杰克逊序列化声明性链接(球衣)
【发布时间】:2015-01-15 07:52:08
【问题描述】:

我在我的项目中使用声明式链接。我的杰克逊映射器配置是

final ObjectMapper mapper = new ObjectMapper();
    mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
    mapper.configure(MapperFeature.AUTO_DETECT_FIELDS, false);
    mapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false);
    mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
    mapper.configure(MapperFeature.AUTO_DETECT_SETTERS, false);
    mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

由于我禁用了任何类型的自动检测,注入的链接如

    @InjectLinks({

@InjectLink(rel = "bookmark", resource = ConnectionsResource.class, style = Style.ABSOLUTE_PATH) })
@JsonProperty("links")
Link[] links;

被序列化为一个空的 JSON 对象(因为“链接”中的所有字段都没有用 @JsonProperty 注释)。

如何在不更改我的全局映射器配置的情况下仅为字段 relhref 启用链接序列化?

【问题讨论】:

  • 这是 Jersey 2.x 还是 Link 类型 javax.ws.rs.core.Link
  • 您使用的是哪个 JSON 提供程序?我想测试一下
  • <groupId>com.fasterxml.jackson.jaxrs</groupId><artifactId>jackson-jaxrs-json-provider</artifactId>
  • 所有值都是空的问题,或者是太多不必要的字段的问题。因为我无法重现前者。我可以重现后者,并有一个解决方案
  • 问题是映射器被配置为排除除标记字段之外的所有字段 (@JsonProperty)。此设置无法更改。 Link 类公开的字段未标记,因此未序列化为 json。生成的 JSON 仅包含 "links":[{},{},...]

标签: java json serialization jersey jackson


【解决方案1】:

因此,完成这项工作的一种方法是使用客户序列化程序。您必须为此序列化程序添加一个新模块到ObjectMapper,但这不会影响其余配置。

这是序列化程序

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 java.io.IOException;
import javax.ws.rs.core.Link;

public class LinkSerializer extends JsonSerializer<Link>{

    @Override
    public void serialize(Link link, JsonGenerator jg, SerializerProvider sp) 
            throws IOException, JsonProcessingException {
        jg.writeStartObject();
        jg.writeStringField("rel", link.getRel());
        jg.writeStringField("href", link.getUri().toString());
        jg.writeEndObject();
    }
}

这里是一个测试类

public class TestClass {

    @JsonProperty("links")
    protected List<Link> links;
    protected String name;
    protected String id;
    // getter and setters
}

然后试运行

public static void main(String[] args) throws Exception{

    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
    mapper.configure(MapperFeature.AUTO_DETECT_FIELDS, false);
    mapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false);
    mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
    mapper.configure(MapperFeature.AUTO_DETECT_SETTERS, false);
    mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(Link.class, new LinkSerializer());
    mapper.registerModule(simpleModule);

    Link link1 = Link.fromUri(URI.create("http://localhost:8080/")).rel("one").build();
    Link link2 = Link.fromUri(URI.create("http://localhost:8080/")).rel("two").build();
    TestClass test = new TestClass();
    test.getLinks().add(link1);
    test.getLinks().add(link2);
    String json = mapper.writeValueAsString(test);
    System.out.println(json);
}

产生这个结果

{
  "links" : [ {
    "rel" : "one",
    "href" : "http://localhost:8080/"
  }, {
    "rel" : "two",
    "href" : "http://localhost:8080/"
  } ]
}

希望这会有所帮助。

【讨论】:

  • 感谢LinkSerializer
【解决方案2】:

这是一个使用 Jackson mixin 注释序列化和反序列化 Link 对象的示例,包括所有属性:

@JsonAutoDetect(
        fieldVisibility = JsonAutoDetect.Visibility.NONE,
        getterVisibility = JsonAutoDetect.Visibility.NONE,
        isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonDeserialize(using = LinkMixin.LinkDeserializer.class)
public abstract class LinkMixin extends Link {

    private static final String HREF = "href";

    @JsonProperty(HREF)
    @Override
    public abstract URI getUri();

    @JsonAnyGetter
    public abstract Map<String, String> getParams();

    public static class LinkDeserializer extends JsonDeserializer<Link> {

        @Override
        public Link deserialize(
                final JsonParser p,
                final DeserializationContext ctxt) throws IOException {
            final Map<String, String> params = p.readValueAs(
                    new TypeReference<Map<String, String>>() {});
            if (params == null) {
                return null;
            }
            final String uri = params.remove(HREF);
            if (uri == null) {
                return null;
            }
            final Builder builder = Link.fromUri(uri);
            params.forEach(builder::param);
            return builder.build();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2014-02-12
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 2014-02-13
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多