有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用jaxb和jaxrs禁止在实体属性中使用斜杠“/”

我拥有以下实体:

@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服务,它接受body 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实体的标识符属性中使用斜杠“/”。 今天,我使用一些jaxb适配器来实现这一点,在解组时,它只是从id中删除所有斜杠。 相反,我希望向用户返回一个适当的BAD_请求异常

我尝试在jaxb适配器的unmarshal方法中抛出异常,但似乎jaxrs正在吞并它,只是将标识符设置为null。 如果我们想要覆盖这个行为,我想我必须创建一个新的@Provider,并在javax所使用的解组器中注册一个特殊的ValidationEventHandler。ws。rs.ext.MessageBodyReader创建。 不幸的是,除非我定义了对JAX-RS实现的显式依赖,否则这是不可能的,我希望避免这种依赖

是否有其他选项限制标识符属性中斜杠的使用,而不定义对jersey/resteasy的显式依赖关系,也不处理服务@POST方法中的限制


共 (1) 个答案

  1. # 1 楼答案

    拯救你的是^{}

    不要使用@XmlJavaTypeAdapter进行任何特殊处理。在应用程序类(如果在jersey2)或web中注册ReaderInterceptor。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);

    希望有帮助