根据Jersey的请求查询参数自定义Jackson的反序列化?

时间:2014-08-04 15:39:22

标签: java rest serialization jackson jersey-2.0

我在我的REST api上使用Jackson 24.1 + Jersey 2.10。

为了以自定义格式解析日期,我有一个杰克逊反序列化器,如下所示:

public class JsonDateSerializer extends JsonSerializer<Date>{

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");

    @Override
    public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)
            throws IOException, JsonProcessingException {

        String formattedDate = dateFormat.format(date);

        gen.writeString(formattedDate);
    }

}

但是我想根据用户是否包含给定的请求标头来更改日期的反序列化方式。要做到这一点,我需要在杰克逊的反序列化器中访问Jersey的HttpRequestContext对象...

当JAckson的串行器/反序列化器像这样一起使用时,是否可以访问Jersey的上下文?

谢谢!

2 个答案:

答案 0 :(得分:0)

据我所知,你无法直接从反序列化程序到达HttpRequest,但我在对象中使用了一个标记做了类似的事情。

    @XmlElement(name = "date")
    public String getDate() {
        return (formatFlag) ? dateFormatter1.format(date): dateFormatter2.format(date);
    }

然后当然formatFlag可以是@XmlTransient

答案 1 :(得分:0)

修改

yep ContextResolverFactory为上下文解析器执行缓存...我以不同的方式工作,希望这有帮助 -

为日期创建XMLAdapter作为spring bean

import java.util.Date;
import javax.inject.Inject;
import javax.inject.Named;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.apache.commons.lang3.time.DateFormatUtils;

@Named
public class RequestBasedXMLAdapter extends XmlAdapter<String, Date> {
    @Inject
    private RequestData requestData;

    @Override
    public String marshal(Date value) throws Exception {

        return DateFormatUtils.format(value, requestData.getMyDateFormat());
    }

    @Override
    public Date unmarshal(String value) throws Exception {
        // i am not interested in incoming date
        return new Date();
    }
}

创建请求范围的bean

import javax.inject.Named;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;

@Named
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestData {
    private String myDateFormat;

    public String getMyDateFormat() {
        return myDateFormat;
    }

    public void setMyDateFormat(String myQueryParam) {
        this.myDateFormat = myQueryParam;
    }
}

为JAXBContext

创建上下文解析器
  1. 注入spring应用程序上下文
  2. 从上下文
  3. 获取定义为spring bean的XMLAdapter
  4. 通过修改以下方法

    返回自定义jaxbcontext(实现为装饰器)
    public JAXBMarshaller createMarshaller() throws JAXBException {
        JAXBMarshaller marshaller = delegate.createMarshaller();
        marshaller.setAdapter(adapter);
        return marshaller;
    }
    
    public JAXBUnmarshaller createUnmarshaller() throws JAXBException {
        JAXBUnmarshaller unmarshaller = delegate.createUnmarshaller();
        unmarshaller.setAdapter(adapter);
        return unmarshaller;
    }
    
  5. 现在在您的Resource类中(您已经定义了GET / POST方法)

    1. 注入请求范围的bean RequestData
    2. 从RequestData
    3. 中的query / header param设置dateformat

      将Response类中的Date字段注释为

       @XmlJavaTypeAdapter(RequestBasedXMLAdapter.class)
       private Date myCustomDate = new Date();
      

      现在您应该可以根据您的请求更改日期格式

      另请注意我使用的是Moxy


      OLD ANSWER

      我认为你可以通过返回不同的ObjectMapper来实现这一点......

      尝试

      1. 为ObjectMapper编写ContextResolver
      2. 使用@Context
      3. 注入HTTPHeader
      4. 基于你的标题param return diff。 mapper使用适当的日期格式
      5. 上述方法的缺点是,相同的日期格式将应用于该响应中的所有日期。