2011-05-16 2 views
4

tl; dr version : base64Binary XSD 데이터 형식에 대해 유효하지 않은 base64를 거부하는 JAX-WS의 엄격 모드를 강제 설정하는 방법이 있습니까?JAX-WS에서 base64Binary 데이터의 엄격한 검증을 적용 할 수 있습니까?


긴 버전 : 나는 XSD 유형 base64Binary에 매핑됩니다 이진 데이터를 수신하는 웹 서비스가있다. 서비스를 테스트하는 동안 JAX-WS는 Base64 문자열을 파싱 할 때 매우 관대하다는 것을 알았습니다. 아무리 잘못된 입력이라도 JAX-WS에서 오류를 생성하지 못했습니다.

문제를 설명하는 작은 테스트 서비스와 클라이언트를 만들었습니다. 그것은 더 많거나 적은 그대로 복사 할 수 있습니다 :

서비스 인터페이스 :

@WebService 
public interface ITest2 { 
    @WebMethod 
    void foo(byte[] bs); 
} 

서비스 구현 및 테스트 :

@WebService(endpointInterface="foo.bar.ITest2") 
public class Test2 implements ITest2 { 

    private static final String requestTemplate = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:bar=\"http://bar.foo/\">" + 
      "<soapenv:Header/>" + 
      "<soapenv:Body>" + 
      "<bar:foo>" + 
      "<arg0>%s</arg0>" + 
      "</bar:foo>" + 
      "</soapenv:Body>" + 
      "</soapenv:Envelope>"; 

    private static final String[] testVector = { 
     "////==", 
     "///==", 
     "//==", 
     "/==", 
     "/==/==/==", 
     "&lt;&gt;", 
     "=====", 
     "%%%///%%%==%%" 
    }; 

    private static PrintWriter pw; 

    static { 
     try { 
      pw = new PrintWriter("/tmp/output"); 
     } catch (FileNotFoundException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public static void main(String[] args) throws Exception { 

     Endpoint e = Endpoint.publish("http://localhost:54321/foo", new Test2()); 

     URL requestUrl = new URL("http://localhost:54321/foo"); 

     for(String testVal : testVector) { 
      pw.println("[client] >" + testVal + "<"); 
      HttpURLConnection urlc = (HttpURLConnection) requestUrl.openConnection(); 
      urlc.setRequestProperty("Content-Type", "text/xml;charset=UTF-8"); 

      urlc.setDoOutput(true); 

      OutputStream out = urlc.getOutputStream(); 

      String request = String.format(requestTemplate, testVal); 

      out.write(request.getBytes()); 
      out.flush(); 

      InputStream in = urlc.getInputStream(); 
      int read = -1; 
      byte[] buf = new byte[1024]; 
      while((read = in.read(buf)) != -1) { 
       System.err.print(new String(buf, 0, read)); 
      } 
      System.err.println(); 
     } 

     pw.flush(); 
     pw.close(); 

    } 

    @Override 
    public void foo(byte[] bs) { 
     String encoded; 
     if(bs == null) { 
      encoded = "<null>"; 
     } else if(bs.length == 0) { 
      encoded = "<empty>"; 
     } else { 
      encoded = new String(Base64.encodeBase64(bs)); 
     } 
     pw.println("[server] >" + encoded + "<"); 
    } 

} 

/tmp 디렉토리에 다음과 같은 출력을 생성/출력 (내가 ' 콘솔에 상당히 많은 정보를 기록하는 Jetty를 사용하고있어 걱정하지 않으려 고합니다.)

[client] >////==< 
[server] ><null>< 
[client] >///==< 
[server] ><null>< 
[client] >/w==< 
[server] >/w==< 
[client] >/==< 
[server] ><null>< 
[client] >/==/==/==< 
[server] >/////w==< 
[client] >&lt;&gt;< 
[server] ><empty>< 
[client] >=====< 
[server] >/w==< 
[client] >%%%///%%%==%%< 
[server] >//8=< 

그래서 완전히 엉망입니다. 때로는 null이 표시되며, 때로는 빈 문자열이 표시되고 가비지가 다른 가비지로 바뀌는 경우가 있습니다. 또한 모든 요청은 HTTP 응답 200을 생성하므로 아무도 아무 것도 잘못되었다는 것을 아무도 모를 수 있습니다.

Unmarshaller에 스키마를 추가하여 JAXB가이를 확인하도록 강제 할 수 있음을 알고 있습니다. JAX-WS는 JAXB를 내부적으로 사용하기 때문에 웹 서비스를 위해 JAX-WS를 사용할 수 있기를 바랍니다. 그게 가능한지 어떻게 알 수 있습니까?

저는 Ubuntu에서 Oracle Java 1.6.0_24의 기본 JAX-WS 구현을 사용합니다.

답변

1

엔드 포인트 구현에 com.sun.xml.internal.ws.developer.SchemaValidation annotation을 추가하여 Metro (JAXWS-RI)에서 스키마 유효성 검증을 사용할 수 있습니다 (Test2).

이것은 형식의 SOAP 오류가 발생합니다

... 
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope"> 
    <faultcode>S:Server</faultcode> 
    <faultstring>com.sun.istack.internal.XMLStreamException2: 
     org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 
     'foo' is not a valid value for 'base64Binary'.</faultstring> 
... 

가 기술적으로, 나는 faultcodeS:Client해야한다는 생각을하지만, 무엇을 어떻게 알 수 있습니까.

제 생각에는 구현 방법에 구애받지 않습니다. 그래서 다른 JAX-WS 컨테이너에 코드를 배치한다면, 그 컨테이너에 대한 메커니즘을 사용해야 할 것이다.

+0

구현 관련 특수 효과를 사용해야하지만 사용자가 할 수있는 일은 터무니 없습니다. 이제 OSGI 컨테이너에서이를 사용하는 방법을 알아 내야 만하지만 이것은 또 다른 질문입니다. 또한 주석에 대한 패키지에서 오타를 만들었다 고 생각합니다. 나는 그것이'com.sun.xml.ws.developer'이어야한다고 생각합니다. 아, 나는 또한 클라이언트 오류가되어야한다는 귀하의 우려를 공유합니다 ... – musiKk

+0

@ musiKk - 고마워요 .- 나는 이것을 놓쳤습니다 (IDE 가져 오기 도구, cut'n'paste). 핵심 API 개발자가 라이브러리를 사용할 때 네임 스페이스를 지정합니다. 링크에서 네임 스페이스를 사용하려면 RI를 다운로드하여 [승인] (http://weblogs.java.net/blog/vivekp/archive/2006/12/webservices_in)에 배치해야합니다.html) 부분을 사용하여 기본 구현을 재정의합니다. 어쨌든이 작업을 수행하는 경우 스키마 유효성 검사에 대한 주석이 필요없는 구현을 선택하는 것이 좋습니다. – McDowell

관련 문제