You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring 4.2.4 REST Controller接收XML请求并XSD校验实现咨询

Spring 4.2.4.RELEASE 实现带XSD校验的XML请求REST接口完整方案

我来帮你搞定这个需求,从完善JAXB实体类,到自定义XSD校验的消息转换器,再到配置和异常处理,一步步来:

1. 完善Dummy类的JAXB注解

首先把你的Dummy类补全,JAXB要求必须有无参构造器,同时要明确字段与XML元素的映射关系:

@XmlRootElement(name = "dummy")
@XmlAccessorType(XmlAccessType.FIELD) // 直接用字段映射,无需依赖getter/setter
public class Dummy {
    @XmlElement(name = "id", required = true) // 指定XML元素名,标记为必填项
    private Integer id;
    
    @XmlElement(name = "name", required = true)
    private String name;
    
    // JAXB必须的无参构造器
    public Dummy() {}

    // 补上getter和setter,方便业务逻辑调用
    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2. 自定义带XSD校验的JAXB消息转换器

Spring默认的Jaxb2RootElementHttpMessageConverter不支持XSD校验,我们需要扩展它,加入Schema校验逻辑:

import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;

public class ValidatingJaxb2HttpMessageConverter extends Jaxb2RootElementHttpMessageConverter {
    private Schema schema;

    // 构造器传入本地XSD文件路径(示例路径:resources/xsd/dummy.xsd)
    public ValidatingJaxb2HttpMessageConverter(String xsdResourcePath) throws SAXException, IOException {
        try (InputStream xsdStream = getClass().getClassLoader().getResourceAsStream(xsdResourcePath)) {
            if (xsdStream == null) {
                throw new IOException("XSD file not found at path: " + xsdResourcePath);
            }
            SchemaFactory schemaFactory = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
            this.schema = schemaFactory.newSchema(new org.xml.sax.InputSource(xsdStream));
        }
    }

    @Override
    protected Unmarshaller createUnmarshaller(JAXBContext jaxbContext) throws JAXBException {
        Unmarshaller unmarshaller = super.createUnmarshaller(jaxbContext);
        // 给反序列化器设置校验用的Schema
        unmarshaller.setSchema(schema);
        return unmarshaller;
    }
}

3. 配置Spring MVC消息转换器

在Spring的Java配置类中,注册我们自定义的转换器,替换默认的JAXB转换器:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.xml.sax.SAXException;
import java.io.IOException;
import java.util.List;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        try {
            // 实例化自定义转换器,传入你的XSD文件路径
            ValidatingJaxb2HttpMessageConverter validatingConverter = new ValidatingJaxb2HttpMessageConverter("xsd/dummy.xsd");
            converters.add(validatingConverter);
        } catch (SAXException | IOException e) {
            throw new RuntimeException("Failed to initialize XSD-validating JAXB converter", e);
        }
    }
}

如果使用XML配置方式,可替换为以下配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="com.yourpackage.ValidatingJaxb2HttpMessageConverter">
                <constructor-arg value="xsd/dummy.xsd"/>
            </bean>
        </list>
    </property>
</bean>

4. 优化Controller方法

原Controller方法已可用,但建议明确指定consumes和produces,表明只处理XML请求并返回XML响应:

import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestController
public class DummyController {
    @RequestMapping(
        value = "/insert",
        method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_XML_VALUE,
        produces = MediaType.APPLICATION_XML_VALUE
    )
    @ResponseStatus(HttpStatus.CREATED)
    public Dummy insert(@RequestBody Dummy dummy) {
        // 这里可添加业务逻辑,比如将dummy对象保存到数据库
        return dummy; // 返回的对象会自动序列化为XML响应
    }
}

5. 全局异常处理(可选但推荐)

当XML不符合XSD规则时,会抛出UnmarshalException,添加全局异常处理器可返回友好的错误提示:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.xml.bind.UnmarshalException;

@ControllerAdvice
public class GlobalXmlValidationExceptionHandler {
    @ExceptionHandler(UnmarshalException.class)
    public ResponseEntity<String> handleXmlValidationFailure(UnmarshalException ex) {
        // 提取校验的具体错误信息
        String errorMsg = "XML validation failed: " + ex.getLinkedException().getMessage();
        return new ResponseEntity<>(errorMsg, HttpStatus.BAD_REQUEST);
    }
}

内容的提问来源于stack exchange,提问作者Neok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:55:14