我有以下实体:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = EntityConstants.PARTNER)
public class FilePartner
{
@XmlAttribute(name = EntityConstants.IDENTIFIER, required = true)
@XmlJavaTypeAdapter(RestResourceIdJaxbAdapter.class)
private String identifier;
...
}
这是jaxb适配器:
public class RestResourceIdJaxbAdapter extends XmlAdapter<String, String>
{
@Override
public String unmarshal(String v) throws Exception
{
if (v != null && v.contains("/"))
{
// throw new ApiException(Status.BAD_REQUEST, RestErrorMessages.BAD_REQUEST_SUFFIX, "Identifier must not contain slashes");
return v.replaceAll("/", "");
}
return v;
}
@Override
public String marshal(String v) throws Exception
{
return v;
}
}
我有一个jaxrs服务,它接受带有正文FilePartner的POST请求:
@POST
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response createPartner(FilePartner partner,
@Context UriInfo uriInfo,
@HeaderParam(HttpHeaders.ACCEPT) String acceptHeader)
throws ApiException
{
...
}
我想要实现的是禁止在FilePartner实体的identifier属性中使用斜杠“/”。 今天我这样做是使用一些jaxb适配器,它只是在解组时从id中删除所有斜杠。 相反,我想要的是向用户返回适当的BAD_REQUEST异常。
我尝试在jaxb适配器的unmarshal方法中抛出异常,但似乎jaxrs吞下它并简单地将我的标识符设置为null。 如果我们想要覆盖这种行为,我想我必须创建一个新的@Provider,并在javax.ws.rs.ext.MessageBodyReader创建的unmarshaller中注册一个特殊的ValidationEventHandler。 不幸的是,除非我定义了一个我想避免的JAX-RS实现的显式依赖,否则这是不可能的。
是否还有其他选项来限制标识符属性中斜杠的使用,而没有定义对jersey / resteasy的显式依赖,也没有处理服务的@POST方法中的限制?
答案 0 :(得分:0)
不要使用@XmlJavaTypeAdapter
进行任何特殊处理。在您的Application类(如果在jersey2中)注册ReaderInterceptor
或在之前的web.xml中注册。
import java.io.IOException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
javax.ws.rs.ext.ReaderInterceptor
@Provider
public class ValidationInterceptor implements ReaderInterceptor {
public ValidationInterceptor() {
super();
}
@Override
public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException,
WebApplicationException {
Object o = readerInterceptorContext.proceed();
if (o instanceof FilePartner&& ((FilePartner) o).getIndentifier().contains("/")) {
throw new WebApplicationException(Response.status(400)
.entity("Identifier must not contain a slash")
.build());
}
return o;
}
}
将拦截器注册到Application
,覆盖public Set<Class<?>> getClasses()
方法,例如classes.add(ValidationInterceptor.class);
希望有所帮助。