2017-10-13 166 views
0

禁止在實體屬性斜槓「/」使用情況我有以下實體:如何使用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的服務,接受帶有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實體的dentifier屬性。 今天我正在使用一些jaxb適配器,它可以在解組時從ID中抽取所有斜線。 相反,我想要的是返回一個適當的BAD_REQUEST異常給用戶。

我試着在jaxb適配器的unmarshal方法中拋出異常,但似乎是jaxrs吞嚥它,並簡單地將我的標識符設置爲null。 如果我們想覆蓋這個行爲,我想我必須創建一個新的@Provider,並在javax.ws.rs.ext.MessageBodyReader創建的解組器中註冊一個特殊的ValidationEventHandler。 不幸的是,這是不可能的,除非我定義一個明確的依賴於我想要避免的JAX-RS實現。

是否有任何其他選項來限制標識符屬性中斜槓的使用,而不定義對球衣/ resteasy的顯式依賴關係,並且不處理服務的@POST方法中的限制?

+0

爲什麼你不檢查郵政方法本身的斜線(不適應),並拋出錯誤 – Optional

+0

我希望我可以做到這一點聲明。我在這個問題中說過。 事情是 - 我有幾十個類似的休息服務處理不同但也非常相似類型的實體。 我不想更改所有休息服務的POST方法,但我寧願註釋所有實體。 有人會認爲這是一個常見的非常標準的用例。我想知道爲什麼聲明式實現並不容易。 – mdzh

+0

好吧@mdzh讓我明白。我認爲我們可以解決它:)。您有一個實體在多個休息調用中共享,並且只希望在同一個實體的某個操作中阻止「/」。或者你有很多實體,並且想限制只有一個實體_not_沒有「/」 – Optional

回答

0

拯救你來ReaderInterceptor

不要做使用@XmlJavaTypeAdapter任何特殊處理。註冊一個ReaderInterceptor與您的應用程序類(如果在jersey2中)或如果更早的話在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; 
    } 
} 

而且這樣註冊classes.add(ValidationInterceptor.class);

希望幫助在public Set<Class<?>> getClasses()方法的東西覆蓋攔截到您的Application