Java – can I enforce strict validation of base64binary data in jax-ws?

tl; Dr version: is there any way to force jax-ws strict mode to reject invalid Base64 of base64binary XSD data type?

Longer version: I have a web service that receives binary data, which is mapped to XSD type base64binary When testing the service, I found that Jax - WS is very loose in parsing Base64 strings No matter how invalid my input is, I can't make Jax - WS error

I created a small test service and client to illustrate the problem It can be copied more or less verbatim:

Service interface:

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

Service implementation and testing:

@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 + "<");
    }

}

This produces the following output in / TMP / output (I use jetty, which records a lot on the console and doesn't want to disturb it):

[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=<

So this is a complete mess Sometimes I receive null, sometimes empty strings, and sometimes garbage is replaced by other garbage In addition, each request generates an HTTP reply 200, so no one knows the problem

I know you can force JAXB to verify this by adding a schema to the unmarshaller Since Jax - WS uses JAXB internally, I hope it is possible to enable it for web services Does anyone know if and how this is possible?

I use Oracle Java 1.6.0 on Ubuntu 0_ The default Jax - WS implementation of 24

Solution

You can add com. On the endpoint implementation sun. xml. internal. ws. developer. Schema validation annotation (test2) enables schema validation in Metro (jaxws - RI)

This causes soap errors in the form:

...
<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>
...

Technically, I think the faultcode should be s: client, but I know what

As far as I know, there is no implementation independent way to do this; Therefore, if you deploy your code in another Jax - WS container, you must use the mechanism of that container

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>