【问题标题】:Jersey REST does not return data in the format from Accept headerJersey REST 不会以 Accept 标头的格式返回数据
【发布时间】:2018-01-14 23:15:03
【问题描述】:

CustomObjectResource - REST 服务返回一个简单的 POJO,其中包含文本、长日期和本地日期时间字段。

@Component
@Path("/resource")
public class CustomObjectResource {

    private RandomCOBuilder randomCOBuilder = new RandomCOBuilder();

    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getCustomObject(@Context HttpServletRequest httpRequest) {
        String acceptHeader = httpRequest.getHeader("Accept");//I do not use it in the code. When I debug, this param is correct.
        CustomObject customObject = randomCOBuilder.get();
        return Response
                // Set the status and Put your entity here.
                .ok(customObject)
                // Add the Content-Type header to tell Jersey which format it should marshall the entity into.
                .build();
    }
}

这是我的邮递员。 Part -1 accept=json 状态码为 200,JSON 解析失败。实际上,返回的对象是 XML 格式的。当我选择以 XML 显示结果时,

<customObject>
    <id>5</id>
    <text>CustomObject_5</text>
    <timestamp>2017-08-07 17:17:40</timestamp>
</customObject>

现在,我使用 Accept:application/xml

Part-2 accept xml

它不返回任何东西:404。

我在 Jackson 上使用 SpringBoot。

这是我的 gradle.build

group 'com.ca.training.rest'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile "org.springframework.boot:spring-boot-starter-jetty:1.5.3.RELEASE"
    compile "org.springframework.boot:spring-boot-starter-web:1.5.3.RELEASE"

    compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.8"
    compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.8"

    compile 'javax.ws.rs:javax.ws.rs-api:2.0.1'
    compile "org.springframework.boot:spring-boot-starter-jersey:1.5.3.RELEASE"

    testCompile 'junit:junit:4.12'
}

CustomObject

@XmlRootElement(name = "customObject")
@JsonRootName(value = "customObject")
public class CustomObject {

    private Long id;
    private String text;

    @JsonFormat(pattern = DATE_FORMAT)
    @XmlJavaTypeAdapter(DateTimeAdapter.class)
    private LocalDateTime timestamp;

}

更新

我正在调试。在我的代码中一切正常......但是当我进一步调试时:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timestamp"
    this problem is related to the following location:
        at public java.time.LocalDateTime com.ca.training.rest.example.core.entity.CustomObject.getTimestamp()
        at com.ca.training.rest.example.core.entity.CustomObject
    this problem is related to the following location:
        at private java.time.LocalDateTime com.ca.training.rest.example.core.entity.CustomObject.timestamp
        at com.ca.training.rest.example.core.entity.CustomObject

【问题讨论】:

标签: java spring-boot jackson jersey jsr


【解决方案1】:

这就是解决方案。

1) @XmlAccessorType(XmlAccessType.FIELD) 摆脱错误。否则,它会从字段和 getter 中获取属性。

@XmlRootElement(name = "customObject")
@JsonRootName(value = "customObject")
@XmlAccessorType(XmlAccessType.FIELD)
public class CustomObject {

    private Long id;
    private String text;

    @JsonFormat(pattern = DATE_FORMAT)
    @XmlJavaTypeAdapter(DateTimeAdapter.class)
    private LocalDateTime timestamp;

    //Getters and setters
}

2) 在JerseyConfig 添加杰克逊配置

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        registerEndpoints();
    }

    private void registerEndpoints() {
         register(CustomObjectResource.class);
         register(JacksonConfig.class);//I need this
    }
}

3) 和 Jackson 配置

@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper = objectMapper();

    private ObjectMapper objectMapper() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        objectMapper = builder.build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
        objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
        return objectMapper;
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return objectMapper;
    }
}

现在它可以工作并以 XML 和 JSON 格式返回对象。

接受:应用程序/xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customObject>
    <id>2</id>
    <text>CustomObject_2</text>
    <timestamp>2017-08-08 11:49:47</timestamp>
</customObject>

接受:应用程序/json

{
    "customObject": {
        "id": 3,
        "text": "CustomObject_3",
        "timestamp": "2017-08-08 11:50:25"
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 2013-04-17
    • 2021-10-05
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    相关资源
    最近更新 更多