tl; dr版本:有没有办法强制JAX-WS的严格模式拒绝无效的base64,因为base64Binary
XSD数据类型?我可以在JAX-WS中强制执行base64Binary数据的严格验证吗?
加长版:我有收到这被映射到XSD类型base64Binary
二进制数据的Web服务。在测试服务时,我发现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 = {
"////==",
"///==",
"//==",
"/==",
"/==/==/==",
"<>",
"=====",
"%%%///%%%==%%"
};
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下面的输出/输出(I” m使用Jetty,对控制台记录了相当多的内容,并且不想打扰):
[client] >////==<
[server] ><null><
[client] >///==<
[server] ><null><
[client] >/w==<
[server] >/w==<
[client] >/==<
[server] ><null><
[client] >/==/==/==<
[server] >/////w==<
[client] ><><
[server] ><empty><
[client] >=====<
[server] >/w==<
[client] >%%%///%%%==%%<
[server] >//8=<
所以这是一个完整的混乱。有时我会收到null
,有时候会出现空字符串,有时候垃圾被其他垃圾取代。而且每个请求都会产生一个HTTP答复200,所以没有人知道任何地方出了问题。
我知道您可以强制JAXB通过将模式添加到Unmarshaller
来验证此情况。由于JAX-WS在内部使用JAXB,我希望有可能为Web服务打开它。有人知道这是可能的吗?
我在Ubuntu上使用Oracle Java 1.6.0_24的默认JAX-WS实现。
这是一个令人失望的,你需要使用特定于实现的注释,但你能做什么。现在我只需要找出如何在OSGI容器中使用它,但这是另一个问题。我也认为你在包装上打了一个错字,我认为它应该是'com.sun.xml.ws.developer'。噢,我也分享你的担心,这应该是客户端错误... – musiKk 2011-05-17 08:48:46
@musiKk - 谢谢 - 我错过了(IDE导入工具,然后cut'n'paste。)我期望这是重新部署的一部分,命名空间核心API开发人员在使用库时所做的。要在链接中使用命名空间,您可能需要下载RI并将其放入[认可](http://weblogs.java.net/blog/vivekp/archive/2006/12/webservices_in。html)部分类路径来覆盖默认实现。无论如何,如果您正在这样做,您可能需要选择一个不需要注释进行架构验证的实现。 – McDowell 2011-05-17 10:02:32