如何修改响应的命名空间,如下所示:
老回复:<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:GetAmountResponse xmlns:ns2="http://ws.dsi.otn.com/dab">
<etat>0</etat>
<montant>500.0</montant>
</ns2:GetAmountResponse>
</soap:Body>
</soap:Envelope>
需要新的回复:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAmountResponse xmlns="http://ws.dsi.otn.com/dab">
<etat>0</etat>
<montant>500.0</montant>
</GetAmountResponse>
</soap:Body>
</soap:Envelope>
我想删除ns2 namespce前缀。
答案 0 :(得分:3)
在第一种情况下,GetAmountResponse
位于名称空间http://ws.dsi.otn.com/dab
中,而etat
和montant
位于默认(空)名称空间中。
在您想要的新邮件中,GetAmountResponse
,etat
和montant
都在名称空间http://ws.dsi.otn.com/dab
中。
可以从类的名称空间控制名称空间。在所有名称空间中使用相同的名称空间,您将在同一名称空间中使用它们,使用默认值保留类,并且它们默认为空名称空间。
例如,如果您在Web服务类中有类似的内容:
@WebMethod
public
@WebResult(name = "getAmountResponse", targetNamespace = "http://ws.dsi.otn.com/dab")
AmountResponse getAmount(
@WebParam(name = "getAmountRequest", targetNamespace = "http://ws.dsi.otn.com/dab") AmountRequest request) {
AmountResponse response = new AmountResponse();
response.setEtat(0);
response.setMontant(500.0);
return response;
}
有这样的响应类:
@XmlRootElement
public class AmountResponse {
private int etat;
private double montant;
// getter and setters omitted
}
你将得到第一种肥皂信息。
但是如果你将响应类更改为这样:
@XmlRootElement(namespace = "http://ws.dsi.otn.com/dab")
@XmlAccessorType(XmlAccessType.NONE)
public class AmountResponse {
@XmlElement(namespace = "http://ws.dsi.otn.com/dab")
private int etat;
@XmlElement(namespace = "http://ws.dsi.otn.com/dab")
private double montant;
// getters and setter omitted
}
您将把所有标记放在同一个命名空间中,并获得与您想要的新类型消息等效的内容。我之所以说相当,是因为我认为你不会得到这个:
<GetAmountResponse xmlns="http://ws.dsi.otn.com/dab">
<etat>0</etat>
<montant>500.0</montant>
</GetAmountResponse>
更有可能得到这样的东西:
<ns2:getAmountResponse xmlns:ns2="http://ws.dsi.otn.com/dab">
<ns2:etat>0</ns2:etat>
<ns2:montant>500.0</ns2:montant>
</ns2:getAmountResponse>
这两个消息的“XML含义”相同,尽管它们看起来不一样。
如果你绝对希望它看起来像这样,我认为你必须“低级别”并使用a SOAP handler to intercept the response and modify it之类的东西。但请注意,在消息传输之前更改消息并不是一项微不足道的任务。
答案 1 :(得分:0)
逻辑处理程序足以按预期转换为消息:
package com.ouertani.slim;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.LogicalMessage;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.handler.MessageContext;
/**
*
* @author ouertani
*/
public class MyLogicalHandler implements LogicalHandler<LogicalMessageContext> {
@Override
public boolean handleMessage(LogicalMessageContext messageContext) {
/// extract state and amount
int state = 0;
double amount = 200.0;
transform(messageContext, state, amount);
return false;
}
public boolean handleFault(LogicalMessageContext messageContext) {
return true;
}
public void close(MessageContext context) {
}
private void transform( LogicalMessageContext messageContext, int etat, double montant){
LogicalMessage msg = messageContext.getMessage();
String htom = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
"<soap:Body>"+
"<GetAmountResponse xmlns=\"http://ws.dsi.otn.com/dab\">"+
"<etat>"+etat+"</etat>"+
"<montant>"+montant+"</montant>"+
"</GetAmountResponse>"+
"</soap:Body>"+
"</soap:Envelope>";
InputStream is = new ByteArrayInputStream(htom.getBytes());
Source ht = new StreamSource(is);
msg.setPayload(ht);
}
}
答案 2 :(得分:0)
这是一个非常古老的问题,仍然有待有效回答。本周我遇到了一个非常相似的问题。我的应用程序正在调用由遗留系统提供的 Soap Web 服务,该系统的 XML 响应语法错误,在 XML 声明之前有一些空字符(换行符、制表符或空格)。在我的场景中,我无法更改遗留系统以修复其响应,因此在解析之前更改响应是我唯一的选择。
我已将以下 maven 依赖项添加到我的应用程序中:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.0</version>
</dependency>
然后我注册了一个“com.oracle.webservices.impl.internalspi.encoding.StreamDecoder”的Java SPI自定义实现。此类在 XML 解析之前立即调用,并带有相应的响应 InputStream,因此此时您可以读取响应 InputStream 或包装/代理它并对 jax 进行任何更改-ws 解析前的响应。就我而言,我只是在第一个可见字符之前删除了一些不可见字符。
我的 StreamDecoder SPI 实现:
package sample.streamdecoder;
import com.oracle.webservices.impl.encoding.StreamDecoderImpl;
import com.oracle.webservices.impl.internalspi.encoding.StreamDecoder;
import com.sun.xml.ws.api.SOAPVersion;
import com.sun.xml.ws.api.message.AttachmentSet;
import com.sun.xml.ws.api.message.Message;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
public class MyStreamDecoder implements StreamDecoder {
//JAX-WS default implementation
private static final StreamDecoderImpl streamDecoder = new StreamDecoderImpl();
@Override
public Message decode(InputStream inputStream, String charset, AttachmentSet attachmentSet, SOAPVersion soapVersion) throws IOException {
//Wrapping inputStream
InputStream wrapped = wrapInputStreamStrippingBlankCharactersBeforeXML(inputStream, charset);
//Delegating further processing to default StreamDecoder
return streamDecoder.decode(wrapped, charset, attachmentSet, soapVersion);
}
private InputStream wrapInputStreamStrippingBlankCharactersBeforeXML(InputStream inputStream, String charset) throws IOException {
int WHITESPACE = (int) Charset.forName(charset).encode(" ").get();
int LINE_BREAK = (int) Charset.forName(charset).encode("\n").get();
int TAB = (int) Charset.forName(charset).encode("\t").get();
return new InputStream() {
private boolean xmlBegin = true;
@Override
public int read() throws IOException {
int read = inputStream.read();
if (!xmlBegin) {
return read;
} else {
while (WHITESPACE == read
|| LINE_BREAK == read
|| TAB == read) {
read = inputStream.read();
}
xmlBegin = false;
}
return read;
}
};
}
}
为了注册它,只需创建一个名为“”的文件“META-INF/services/com.oracle.webservices.impl.internalspi.encoding.StreamDecoder”并在第一个写上你的SPI实现的全限定名像这样的行:
文件内容META-INF/services/com.oracle.webservices.impl.internalspi.encoding.StreamDecoder:
sample.streamdecoder.MyStreamDecoder
现在每个响应都会在解析之前传递给您的实现。