Java 我可以在JAX-WS中强制执行Base64二进制数据的严格验证吗?

Java 我可以在JAX-WS中强制执行Base64二进制数据的严格验证吗?,java,jax-ws,base64,Java,Jax Ws,Base64,tl;dr版本:有没有办法强制JAX-WS采用严格模式,拒绝base64BinaryXSD数据类型的无效base64 更长的版本:我有一个web服务,它接收映射到XSD类型base64Binary的二进制数据。在测试该服务时,我发现JAX-WS在解析Base64字符串时非常宽松。无论我的输入多么无效,我都无法让JAX-WS产生错误 我创建了一个小型测试服务和客户机来说明这个问题。它可以或多或少逐字复制: 服务接口: @WebService public interface ITest2 {

tl;dr版本:有没有办法强制JAX-WS采用严格模式,拒绝
base64Binary
XSD数据类型的无效base64


更长的版本:我有一个web服务,它接收映射到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 + "<");
    }

}
@WebService(endpointInterface=“foo.bar.ITest2”)
公共类Test2实现了ITest2{
私有静态最终字符串requestTemplate=“”+
"" +
"" +
"" +
%s+
"" +
"" +
"";
私有静态最终字符串[]testVector={
"////==",
"///==",
"//==",
"/==",
"/==/==/==",
"",
"=====",
"%%%///%%%==%%"
};
专用静态打印机;
静止的{
试一试{
pw=新的打印写入程序(“/tmp/output”);
}catch(filenotfounde异常){
抛出新的运行时异常(e);
}
}
公共静态void main(字符串[]args)引发异常{
端点e=端点。发布(“http://localhost:54321/foo“,新Test2());
URL requestUrl=新URL(“http://localhost:54321/foo");
for(字符串testVal:testVector){

println(“[client]>”+testVal+“+encoded+”通过在端点实现上添加-
Test2
,可以在Metro(JAXWS-RI)中启用模式验证

这会导致表单出现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>
...
。。。
S:服务器
com.sun.istack.internal.xmlStreamException 2:
org.xml.sax.SAXParseException:cvc数据类型有效。1.2.1:
“foo”不是“base64Binary”的有效值。
...
从技术上讲,我认为应该是
S:Client
,但我知道什么呢


据我所知,没有实现无关的方法可以做到这一点;因此,如果您将代码部署到另一个JAX-WS容器中,您将不得不使用该容器的机制。

您需要使用特定于实现的注释,但您能做些什么?现在我只需要了解如何在OSGI容器中使用它但是这是另一个问题。我还认为你在注释包中输入了一个错误;我认为应该是
com.sun.xml.ws.developer
。哦,我也和你一样担心这可能是一个客户端错误…@musiKk-谢谢-我错过了(IDE导入工具,然后剪切粘贴)我希望这是核心API开发人员在使用库时重新命名的一部分。若要在链接中使用名称空间,您可能需要下载RI并将其放置在类路径的一部分中,以覆盖默认实现。如果仍要这样做,您可能希望选择一个不需要注释的实现或模式验证。
...
<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>
...