我知道杰克逊允许我们为特定的域/实体/模型使用自定义序列化器,如下所示:
@JsonSerialize(using = CustomSerializer.class)
public class SimpleDomain {
}
并且,是否有任何想法为某些requestMapping指定自定义序列化程序, (仅针对特定的requestMapping(该方法),而不是设置全局objectMapper。)像这样:
@RequestMapping(method = RequestMethod.GET, value = "hello")
@JsonSerialize(nullsUsing = NullToEmptyStrSerializer.class)
public @ResponseBody
Object get() {
return new HashMap<String, Object>() {{
put("aa", null);
put("bb", "");
}};
}
我执行上面的代码,它返回:
{
"aa": null,
"bb": ""
}
而不是:
{
"aa": "",
"bb": ""
}
我想要的。
NullToEmptyStrSerializer:
public class NullToEmptyStrSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeString("");
}
}
或者,我可以在NullToEmptyStrSerializer中获取HttpServletRequest,如果是,我可以在NullToEmptyStrSerializer中过滤。
答案 0 :(得分:0)
这可能是已知的限制(@JsonSerialize
nullUsing
选项不适用于String
属性)并在此github issue中报告。
计划在jackson 2.9.3 and 2.8.11
发布。
修复将在2.9.3中,但我也将其反向移植到2.8分支以防万一 2.8.11可能会在某个时候发布。
答案 1 :(得分:0)
最后,我自己发现了它。 我意识到了这一点:
或者,我可以在NullToEmptyStrSerializer中获取HttpServletRequest,如果是,我可以在NullToEmptyStrSerializer中过滤。
自定义将null
转换为""
以获取特定网址(RequestMapping
)
定义一个bean以保持ApplicationContext
存储在静态字段中,也就是静态getter:
@Component
public class ContextHolder {
private static ApplicationContext applicationContext;
@Resource
public void setApplicationContext(ApplicationContext applicationContext) {
ContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext get(){
return applicationContext;
}
}
在下面定义一个bean,这个bean将为每个请求创建,因此,我将ServletRequest
存储在这个bean中。
@Component("servletRequestHolder")
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ServletRequestHolder {
@Resource
private HttpServletRequest request;
public HttpServletRequest getRequest(){
return request;
}
}
然后,需要一个序列化器。
public class NullToEmptyStringSerializer extends JsonSerializer.None {
public static List<String> convertUrls = new ArrayList<String>(){{
add("/hello");
}};
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
HttpServletRequest request = ContextHolder.get().getBean(ServletRequestHolder.class).getRequest();
if (request != null) {
String currentUrl = request.getRequestURI();
boolean match = convertUrls.contains(currentUrl);
if (match) {
gen.writeString("");
} else {
gen.writeObject(null);
}
} else {
gen.writeObject(null);
}
}
}
将Serializer添加到objectMapper:
DefaultSerializerProvider.Impl sp = new DefaultSerializerProvider.Impl();
sp.setNullValueSerializer(new NullToEmptyStringSerializer());
objectMapper.setSerializerProvider(sp);
最后,测试一下:
@GetMapping({"hello", "hello1"})
public Object get() {
return new HashMap<String, Object>() {{
put("a", null);
put("b", "");
}};
}
如果请求localhost:20000/hello
,客户会收到:
{
"aa": "",
"bb": ""
}
对于请求localhost:20000/hello1
,客户端会收到:
{
"aa": null,
"bb": ""
}