【fasterxml.jackson】字段(反)序列号问题Access.WRITE_ONLY
问题描述:在基于Spring MVC的RESTful接口,当接口中请求参数Bean的字段被 @JsonProperty(access = Access.WRITE_ONLY) 约束时,通过postman调用rest接口,可以得到该字段可以值,也就是get/set是没问题的。
当通过feign接口调用时,该字段会被序列化为字节码传到所在服务的机器上,当反序列化该字段时,得到的字段值为null
原因:被Access.WRITE_ONLY约束的字段值不会被序列化进去,所以对方获得的值为null。而postman直调服务器时,是将值直接序列化为字节码,所以可以获取到值。
@JsonProperty( access = Access.WRITE_ONLY ) private String userPassword; @JsonIgnore private String uuid;
如下,为@JsonProperty内部结构。
package com.fasterxml.jackson.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotation public @interface JsonProperty { String USE_DEFAULT_NAME = ""; int INDEX_UNKNOWN = -1; String value() default ""; boolean required() default false; int index() default -1; String defaultValue() default ""; JsonProperty.Access access() default JsonProperty.Access.AUTO; public static enum Access { AUTO, READ_ONLY, WRITE_ONLY, READ_WRITE; private Access() { } } }
解决方法:摒弃该约束字段的Bean,新建一个Bean进行访问,调feign接口。
扩展知识点:
1. jackson依赖jar导入
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.1</version> </dependency>
2. 关于jackson中@JsonIgnore
和 @JsonProperty
的说明
可参考:http://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonProperty.Access.html
3. 示例代码验证
首先,新建一个用于传参的Bean,UserTest,其中字段被@JsonProperty(分为Access.WRITE_ONLY、Access.READ_ONLY)和@JsonIgnore修饰
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @JsonInclude(JsonInclude.Include.NON_NULL) public class UserTest { private String userName; @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String userPassword; @JsonIgnore private String uuid; @JsonProperty(access = JsonProperty.Access.READ_ONLY) private String readOnly; @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private String trans = "0"; }
其次,新建一个接口test
@PostMapping(value = "/test") public String test(@RequestBody UserTest test) { log.info("请求参数 -->{}", JSON.toJSONString(test)); return "success"; }
启动服务,通过postman调用接口
打印结果如下:
2020-01-25 11:57:53.450 请求参数 -->{"trans":"0","userName":"name","userPassword":"123456"}
以上,通过对结果分析,发现用postman的body体内,所设置的字段readOnly未被打印,说明在该字段未被set(说明了被READ_ONLY修饰的字段仅支持get方法)进去,而字段trans能被打印,是因为该字段有被初始化值(有初始化值的字段无论设置为READ_ONLY或WRITE_ONLY修饰,都在不设置的情况下展示默认值)。
因此,总结如下:
WRITE_ONLY:仅做反序列化操作。
READ_ONLY:仅做序列化操作。
本文链接:https://www.cnblogs.com/cheng2839
关于博主:评论和私信会在第一时间回复。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!