没有注释的 Jersey 验证
Jersey validation without annotations
我有一个基于 Jersey 的应用程序,我想为输入添加验证。
@POST
@Produces(APPLICATION_JSON) @Consumes(APPLICATION_JSON)
public SomeResponce myMethod(@Valid MyBean myBean)
问题是我的bean是由protostuff生成的,我无法添加验证注解。我找到了如何在没有 annotation/xml 的情况下验证 bean 的方法:
http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-programmatic-api
但我对 Jersey 非常不熟悉,无法在文档中找到如何在不使用 bean 中的注释的情况下将此自定义验证器添加到 Jersey。有什么办法吗?
球衣版本 - 2.8
一个简单的方法(也可能用于球衣)是在引用的 xml 文件中 configure hibernate validator via XML. Place the validation.xml file in the META-INF folder and create constraint-mappings:
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();
}
}
使用 MessageBodyReader 提供 "custom" 反序列化。此自定义将简单地向标准解串器(unmarshaller)提供一个 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
}
}
我有一个基于 Jersey 的应用程序,我想为输入添加验证。
@POST
@Produces(APPLICATION_JSON) @Consumes(APPLICATION_JSON)
public SomeResponce myMethod(@Valid MyBean myBean)
问题是我的bean是由protostuff生成的,我无法添加验证注解。我找到了如何在没有 annotation/xml 的情况下验证 bean 的方法: http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-programmatic-api
但我对 Jersey 非常不熟悉,无法在文档中找到如何在不使用 bean 中的注释的情况下将此自定义验证器添加到 Jersey。有什么办法吗?
球衣版本 - 2.8
一个简单的方法(也可能用于球衣)是在引用的 xml 文件中 configure hibernate validator via XML. Place the validation.xml file in the META-INF folder and create constraint-mappings:
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();
}
}
使用 MessageBodyReader 提供 "custom" 反序列化。此自定义将简单地向标准解串器(unmarshaller)提供一个 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
}
}