Spring MVC 5 Rest API 使用 JAXB

问题描述

我们正在将 Jersey 端点迁移到 Spring MVC Rest 端点。这些端点使用并生成 XML。但是 Spring MVC 无法转换 XML 输入 bean,因为 XML 标记和 Bean 的属性名称不同。我必须将请求作为字符串并使用 JAXB 显式转换它。有没有更好的方法来做到这一点?

网页配置

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {
    
        public static final String JAXB_PACKAGE = "com.comp.platform.dataholder";
    
        @Autowired
        private Jackson2ObjectMapperBuilder builder;
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    
            converters.add(new StringHttpMessageConverter());
            converters.add(new FormHttpMessageConverter());
            converters.add(createXmlHttpMessageConverter());
    
            converters.add(createMappingJacksonHttpMessageConverter(builder));
            // converters.add(createMappingJackson2XmlHttpMessageConverter(xmlMapper));
    
            Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter = new Jaxb2RootElementHttpMessageConverter();
            jaxb2RootElementHttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML));
            converters.add(jaxb2RootElementHttpMessageConverter);
    
        }
    
        @Bean
        public Jackson2ObjectMapperBuilder customJson() {
            return new Jackson2ObjectMapperBuilder().indentOutput(true).serializationInclusion(JsonInclude.Include.NON_NULL)
                    .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE).failOnUnkNownProperties(false);
        }
    
        @Bean
        @Primary
        public ObjectMapper createObjectMapper(Jackson2ObjectMapperBuilder builder) {
    
            ObjectMapper mapper = builder.build();
            mapper.setSerializationInclusion(Include.NON_NULL);
            return mapper;
        }
    
        @Bean
        public Jaxb2Marshaller jaxb2Marshaller() {
            Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
            marshaller.setClassesToBeBound(NonFinancialDataHolder.class,JaxbDataHolder.class,ViestimateDataHolder.class,CTRequest.class,com.app.rest.PolicyDetailRequest.class,com.app.rest.TransactionSubmitRequest.class,com.app.rest.AgentSuppressInfoRequest.class);
    
            return marshaller;
        }
    
        /**
         * @return
         */
        @Bean
        public MappingJackson2HttpMessageConverter createMappingJacksonHttpMessageConverter(
                Jackson2ObjectMapperBuilder builder) {
            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            converter.setobjectMapper(builder.build());
            return converter;
        }
        
        @Autowired
        Jaxb2Marshaller jaxb2Marshaller;
    
        private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
            Assert.notNull(jaxb2Marshaller,"Jaxb Marshaller dependency required");
            MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(jaxb2Marshaller);
            xmlConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML));
    
            return xmlConverter;
        }
    
        public JAXBContext getMarshaller() throws JAXBException {
            return JAXBContext.newInstance(JAXB_PACKAGE);
        }
    
    }

@XmlAccessorType(XmlAccesstype.FIELD)
@XmlType(name = "",propOrder = {
        "_UserId","_Password","_RequestDateTime","_Policy"
})
    @XmlRootElement(name = "PolicyDetailRequest")
    public class PolicyDetailRequest
    {
        @XmlElement(name = "UserId")
        protected String _UserId;
        @XmlElement(name = "Password")
        protected String _Password;
        @XmlElement(name = "RequestDateTime")
        protected String _RequestDateTime;
        @XmlElement(name = "Policy")
        protected String _Policy;
    }

休息端点

@Slf4j 
@RestController    
@RequestMapping("/api")  
public class api
{
    @Autowired
        Jaxb2Marshaller jaxb2Marshaller;

    @PostMapping(value="/PolicyResponse",produces=MediaType.APPLICATION_XML_VALUE,consumes = MediaType.APPLICATION_XML_VALUE)
    @ResponseBody
    public PolicyDetailResponse getPolicyResponse(@RequestBody String data)
    {
        PolicyDetailRequest request = (PolicyDetailRequest) jaxb2Marshaller.unmarshal(new StreamSource(new StringReader(data)));
        PolicyDetailResponse response = new PolicyDetailResponse();
        InternetRSHandler handler = new InternetRSHandler();
    
        response= handler.getPolicyRSResponse(request);
    
        return response;
    
    }
}

输入请求

<PolicyDetailRequest>
    <UserId>1234567890</UserId> 
    <Password>password</Password> 
    <RequestDateTime>20200420-15:07:23</RequestDateTime>
    <Policy>A76ABCD12</Policy>
</PolicyDetailRequest>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)