测试期间Jackson的Access.WRITE_ONLY为空

时间:2017-08-14 17:08:16

标签: java rest testing spring-boot jackson

我目前正在玩Jackson的de /序列化功能,我遇到了一个问题,我不知道如何解决。

在我的测试期间,@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)注释会被忽略,它只会显示null。 但是,例如邮差一切都按预期工作。

我只使用Spring Starter和Web Starter以及Test Starter依赖项。

示例代码:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@RestController
class JacksonExampleRestController {

    @PostMapping("/api")
    public void getResti(@RequestBody JacksonModel jacksonModel) {
        System.out.println(jacksonModel.getId());
        System.out.println(jacksonModel.getPassword());
    }
}

class JacksonModel {

    private String id;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class DemoApplicationTests {

    private MockMvc mockMvc;

    @Before
    public void setUp() {

        JacksonExampleRestController jacksonExampleRestController = new JacksonExampleRestController();

        mockMvc = MockMvcBuilders.standaloneSetup(jacksonExampleRestController)
                .build();
    }

    @Test
    public void testJackson() throws Exception {
        JacksonModel jacksonModel = new JacksonModel();
        jacksonModel.setId("id");
        jacksonModel.setPassword("password");

        mockMvc.perform(post("/api").
                contentType(APPLICATION_JSON_UTF8)
                .content(convertObjectToJsonBytes(jacksonModel)));
    }

    public static byte[] convertObjectToJsonBytes(Object object)
            throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsBytes(object);
    }
}

这是默认行为吗?我是否必须在测试中配置某些内容,还是我现在看不到的其他内容?

3 个答案:

答案 0 :(得分:2)

忽略所有注释可能会出现问题。要处理更好的配置,您可以实现自定义JacksonAnnotationIntrospector

public class IgnoreJacksonWriteOnlyAccess extends JacksonAnnotationIntrospector {

    @Override
    public JsonProperty.Access findPropertyAccess(Annotated m) {
        JsonProperty.Access access = super.findPropertyAccess(m);
        if (access == JsonProperty.Access.WRITE_ONLY) {
            return JsonProperty.Access.AUTO;
        }
        return access;
    }
}

然后,在实例化映射器之后:

mapper.setAnnotationIntrospector(new IgnoreJacksonWriteOnlyAccess());

答案 1 :(得分:0)

为您的ObjectMapper添加行:

mapper.disable(MapperFeature.USE_ANNOTATIONS);

答案 2 :(得分:0)

我遇到了同样的问题,设置也类似。问题出在测试输入数据中。基本上,writeValueAsBytes()会在完全按照注释的指示进行序列化时忽略密码。

请注意,Access.WRITE_ONLY的基本含义是“仅Setter”或“仅反序列化”。