gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 03:44:19 26 4
gpt4 key购买 nike

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


更长的版本:我有一个 Web 服务接收映射到 XSD 类型 base64Binary 的二进制数据。在测试该服务时,我发现 JAX-WS 在解析 Base64 字符串时非常宽松。无论我的输入多么无效,我都无法让 JAX-WS 产生错误。

我创建了一个小型测试服务和客户端来说明问题。它可以或多或少地逐字复制:

服务接口(interface):

@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/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 在 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>
...

从技术上讲,我相信 faultcode应该是 S:Client,但我知道什么。

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

关于java - 我可以在 JAX-WS 中强制执行对 base64Binary 数据的严格验证吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6017501/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com