简体   繁体   English

Jersey 无注释验证

[英]Jersey validation without annotations

I have a Jersey-based application and I want to add validation to input.我有一个基于 Jersey 的应用程序,我想为输入添加验证。

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

Problem is that my beans are generated by protostuff and I cant add validation annotations.问题是我的 bean 是由 protostuff 生成的,我无法添加验证注释。 I've found the way how to validate beans without annotation/xml: http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-programmatic-api我找到了如何在没有注释/xml 的情况下验证 bean 的方法: http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-programmatic-api

But Im very unfamiliar with Jersey and cant find in docs how to add this custom validators to Jersey without use of annotations in bean.但我对 Jersey 非常不熟悉,无法在文档中找到如何在不使用 bean 中的注释的情况下将此自定义验证器添加到 Jersey。 Is any way to do it?有什么办法吗?

Jersey version - 2.8 Jersey 版本 - 2.8

An easy way (and possible with jersey too) is to configure hibernate validator via XML .一种简单的方法(也可能与 jersey 一起使用)是通过 XML 配置 hibernate 验证器 Place the validation.xml file in the META-INF folder and create constraint-mappings in the referenced xml file:将 validation.xml 文件放在 META-INF 文件夹中,并在引用的 xml 文件中创建约束映射

src/main/resources/META-INF/validation.xml (the validation.xml must be in the folder META-INF in your classpath): 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 : 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 : 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 : 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();
    }
}

Use a MessageBodyReader to provide "custom" de-serialization.使用 MessageBodyReader 提供“自定义”反序列化。 This customization will simply provide an XSD schema to the standard deserializer (unmarshaller), which will validate all your types.此自定义将简单地向标准反序列化器(unmarshaller)提供一个 XSD 模式,它将验证您的所有类型。 This will happen BEFORE getting to your method.这将在进入您的方法之前发生。 Here is a quick example:这是一个简单的例子:

@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;
    }
}

with this addition, you can now have simply:有了这个添加,您现在可以简单地:

@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
    } 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM