1

我有一个基于 Jersey 的应用程序,我想向输入添加验证。

@POST
@Produces(APPLICATION_JSON) @Consumes(APPLICATION_JSON)
public SomeResponce myMethod(@Valid MyBean myBean)

问题是我的 bean 是由 protostuff 生成的,我无法添加验证注释。我找到了如何在没有注释/xml的情况下验证bean的方法:http: //docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-programmatic-api

但是我对泽西岛非常不熟悉,并且无法在文档中找到如何在不使用 bean 注释的情况下将这个自定义验证器添加到泽西岛。有什么办法吗?

泽西版 - 2.8

4

2 回答 2

1

一种简单的方法(也可以使用 jersey)是通过 XML 配置休眠验证器。将 validation.xml 文件放在 META-INF 文件夹中,并在引用的 xml 文件中创建约束映射:

src/main/resources/META-INF/validation.xml(validation.xml 必须在类路径中的 META-INF 文件夹中):

<validation-config
        xmlns="http://jboss.org/xml/ns/javax/validation/configuration" version="1.1">
    <constraint-mapping>META-INF/mapping.xml</constraint-mapping>
</validation-config>

src/main/resources/META-INF/mapping.xml

<constraint-mappings
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
        xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1">

    <default-package>com.example</default-package>
    <bean class="MyBean" ignore-annotations="true">
        <field name="name">
            <constraint annotation="javax.validation.constraints.Size">
                <element name="max">5</element>
            </constraint>
            <constraint annotation="javax.validation.constraints.NotNull">
            </constraint>
        </field>
    </bean>
</constraint-mappings>

src/main/java/com/example/MyBean.java

package com.example;

public class MyBean {

    private String name;

    public String getName() {
        return name;
    }

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

src/main/java/com/example/MyResource.java

package com.example;
import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@Path("/api")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class MyResource {

    @POST
    public String postIt(@Valid MyBean bean) {
        return bean.getName();
    }
}
于 2016-04-08T16:39:06.243 回答
1

使用 MessageBodyReader 提供“自定义”反序列化。这种定制只会为标准反序列化器(解组器)提供一个 XSD 模式,它将验证您的所有类型。这将在使用您的方法之前发生。这是一个简单的例子:

@Provider
@Consumes("application/xml")
public class MyMsgBodyReader implements MessageBodyReader {

@Override
public boolean isReadable(Class type, java.lang.reflect.Type genericType, Annotation[] annotations, MediaType mediaType) {
    return type.isAnnotationPresent(XmlRootElement.class);
}

@Override
public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {

    try {
        JAXBContext ctx = JAXBContext.newInstance(type);
        Unmarshaller unmarhsaller = ctx.createUnmarshaller();

        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        URL schemaFile = HelloWolrd.class.getResource("XSD_FILE_LOCATION");
        if (schemaFile != null) {
            Schema schema = sf.newSchema(schemaFile);
            unmarhsaller.setSchema(schema);
        }
        else {
           System.out.println("not validating xml");
        }

        return unmarhsaller.unmarshal(entityStream);
    }
    catch (JAXBException e) {
        logger.log(e.toString(), Level.WARNING);
    }

    return null;
    }
}

通过此添加,您现在可以简单地拥有:

@Path("HelloWolrd")
public class HelloWorld{

    @POST
    @Produces(MediaType.APPLICATION_XML)
    @Consumes(MediaType.APPLICATION_XML)
    public Response query(HelloRequest rqst) {
        System.out.println(rqst.getSomeField()); // <-- ALREDAY validated
    } 
}
于 2018-08-04T17:14:02.613 回答