加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 我可以在JAX-WS中强制执行base64Binary数据的严格验证吗

发布时间:2020-12-15 02:25:39 所属栏目:Java 来源:网络整理
导读:tl; dr version:有没有办法强制JAX-WS的严格模式拒绝base64Binary XSD数据类型的无效base64? 更长的版本:我有一个Web服务接收二进制数据,它被映射到XSD类型base64Binary.在测试服务时,我发现JAX-WS在解析Base64字符串时非常宽松.无论我的输入多么无效,我
tl; dr version:有没有办法强制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,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 / output中产生以下输出(我使用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,我希望有可能为Web服务启用它.有人知道这是否可能以及如何?

我在Ubuntu上使用Oracle Java 1.6.0_24的默认JAX-WS实现.

解决方法

您可以通过在端点实现上添加 com.sun.xml.internal.ws.developer.SchemaValidation annotation(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>
...

从技术上讲,我认为faultcode应该是S:Client,但我知道什么.

据我所知,没有与实现无关的方法来做到这一点;因此,如果您将代码部署在另一个JAX-WS容器中,则必须使用该容器的机制.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读