如何在未知的XML标签上失败?

时间:2019-05-10 08:52:59

标签: java xml spring spring-boot jackson

在我的Spring Boot 2.1应用程序中,我想提供一个XML-HTTP-API。

基于现有的XSD-Schema,我生成了Java类(使用jaxb)。生成的代码大致如下:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerRequestType", propOrder = {
    "firstName",
    "lastName"
})
public class CustomerRequestType {

    @XmlElement(name = "firstName")
    protected List<FirstNameType> firstName;
    @XmlElement(name = "lastName")
    protected List<LastNameType> lastName;

    // ...getter methods...
}

我的Spring Boot RestControllers看起来像这样:

@RestController
@RequestMapping("customer.xml")
public class CustomerController {

    @PostMapping
    public CustomerResponseType postCustomer(@RequestBody CustomerRequestType anfrage) {
      // ...business code...
    }
}

当反序列化带有未知标签或类似属性的请求时,如何让带有杰克逊的弹簧启动失败?

<Customer>
    <firstName>Bob</firstName>
    <lastName>Schmitt</lastName>

    <unknownTag unknownProperty="1234"/>

</Customer>

我试图通过设置此属性来将杰克逊设置为严格模式(尽管文档告诉我,无论如何默认将其设置为true),但是Web服务仍返回状态200:

spring.jackson.deserialization.fail-on-unknown-properties=true

2 个答案:

答案 0 :(得分:1)

您需要检查Spring-Boot使用哪个转换器反序列化XML有效负载。您的情况可能是Jaxb2RootElementHttpMessageConverter。要使用Jackson属性,您需要使用MappingJackson2XmlHttpMessageConverter,它可以检查未知属性并抛出UnrecognizedPropertyException异常。要自定义Jackson的映射器配置,我们可以使用Jackson2ObjectMapperBuilderCustomizer bean。

看下面的例子:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

@Configuration
public class JacksonMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private Jackson2ObjectMapperBuilderCustomizer customizer;

    public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
        Jackson2ObjectMapperBuilder xmlBuilder = Jackson2ObjectMapperBuilder.xml();
        customizer.customize(xmlBuilder);

        return new MappingJackson2XmlHttpMessageConverter(xmlBuilder.build());
    }

    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2XmlHttpMessageConverter());

        super.configureMessageConverters(converters);
    }
}

如果您想使用Jackson来反序列化带有JAXB注释的类,请考虑使用JaxbAnnotationModule

答案 1 :(得分:0)

据我所知,Jackson主要用于JSON数据。它还支持XML和一些JAXB注释。但是它不支持XML模式验证。

看来,您实际上是在寻找模式验证。然后,您应该将JAXB用作XML编组器。

另请参阅: Spring JAXB - Unmarshalling an XML document with schema validation