java - 在 JPA/JAX-RS Web 服务中验证 JAXBElement

标签 java validation jaxb jersey eclipselink

我有一个 JAX-RS 网络服务 (Jersey),它是 JPA (EclipseLink) 实体的 CRUD 接口(interface)。我的实体是从数据库表自动生成的,我用 JAXB 注释对它们进行了注释,以便它们可以编码到 XML 或从 XML 中解码。我的资源方法在需要时将 JAXBElement 对象作为参数。

我没有 XSD,但是,我愿意编写一个来验证请求中收到的 XML。但是,我不知道如何启动验证。 Jersey 会自动处理编码/解码,我发现的任何有关验证的引用资料都是在该级别完成的。

有人知道展示如何执行此操作的示例/教程吗?

谢谢!

最佳答案

您可以通过创建自定义 MessageBodyReader 来处理这个问题。以下示例基于客户模型:

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URL;

import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import javax.xml.XMLConstants;
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;

@Provider
@Consumes("application/xml")
public class ValidatingReader implements MessageBodyReader<Customer> {

    @Context
    protected Providers providers;

    private Schema schema;

    public ValidatingReader() {
        try {
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            URL schemaURL = null;
            schema = sf.newSchema(schemaURL);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) {
        return arg0 == Customer.class;
    }

    public Customer readFrom(Class<Customer> arg0, Type arg1, Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
            throws IOException, WebApplicationException {
        try {
            JAXBContext jaxbContext = null;
            ContextResolver<JAXBContext> resolver = providers.getContextResolver(JAXBContext.class, arg3);
            if(null != resolver) {
                jaxbContext = resolver.getContext(arg0);
            }
            if(null == jaxbContext) {
                jaxbContext = JAXBContext.newInstance(arg0);
            }
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            unmarshaller.setSchema(schema);
            return (Customer) unmarshaller.unmarshal(arg5);
        } catch(JAXBException e) {
            throw new RuntimeException(e);
        }
    }

}

关于java - 在 JPA/JAX-RS Web 服务中验证 JAXBElement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3428273/

相关文章:

java - 通过 http 寻找 api/协议(protocol)

java - package-info.java 是如何工作的?

java - 可以使用配置文件来描述 JAXB 导出吗?

Java Enum 找不到符号错误

java - 如何将 Joda-Time DateTime 转换为 java.util.Date ,反之亦然?

JavaScript - 下拉验证选择

javascript - 使用javascript验证html中的输入文本字段

java - 有什么方法可以找出 vespa.ai 中的结果匹配百分比吗?

java - 构建 Java 包(javac 到所有文件)

javascript - 使用 Yup 的表单验证检查输入值是否相等