仅使用 JAX-WS 在请求的字符串参数上添加 CDATA
Add CDATA on request's string parameter using only JAX-WS
我有一个使用 CXF 生成的 jax-ws 客户端
请求有一个包含 xml 的字符串参数 (MGRequest),一切正常,但生成的请求是这样的:
<S:Body>
<ns5:MGRequest><mytag>hello</mytag></ns5:MGRequest>
</S:Body>
我需要像这样生成正文:
<S:Body>
<ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest>
</S:Body>
(因为我无法控制服务器..)
客户端就像一个标准的 jax-ws:
@WebService(name = "ServiceSoap")
@XmlSeeAlso({ ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ServiceSoap {
@WebMethod(operationName = "ProcessMessage")
@WebResult(name = "MGResponse")
public String processMessage(
@WebParam(partName = "input", name = "MGRequest") String input);
}
我这样称呼:
Service client = new Service(url);
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler()));
ServiceSoap service = client.getServiceSoap();
String msgToSend = JaxbUtil.jaxbObjToString(xmlObj, false);
String response = service.processMessage(msgToSend);
我尝试在 @WebParam
之前添加 @XmlJavaTypeAdapter(CDataAdapter.class)
但结果是:
<S:Body>
<ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest>
</S:Body>
其中 CDataAdapter:
public class CDataAdapter extends XmlAdapter<String, String> {
@Override
public String marshal(String v) throws Exception {
return "<![CDATA[" + v + "]]>";
}
@Override
public String unmarshal(String v) throws Exception {
return v;
}
}
知道如何存档吗?
谢谢
经过一个晚上的工作,我找到了解决方案:
像这样向客户端添加 javax.xml.ws.handler.Handler
:
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler(), new CDataHandler()));
我的 HandlerFactory 构建处理程序的位置:
public static HandlerResolver build(final Handler... handlers) {
return new HandlerResolver() {
@Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
if (handlers != null) {
for (Handler handler : handlers) {
handlerChain.add(handler);
}
}
return handlerChain;
}
};
}
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class CDataHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public void close(MessageContext context) {
}
@Override
public boolean handleMessage(SOAPMessageContext soapMessage) {
try {
SOAPMessage message = soapMessage.getMessage();
boolean isOutboundMessage = (Boolean) soapMessage
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// is a request?
if (isOutboundMessage) {
// build a CDATA NODE with the text in the root tag
Node cddata = (Node) message.getSOAPPart().createCDATASection(
message.getSOAPBody().getFirstChild().getTextContent());
// add the CDATA's node at soap message
message.getSOAPBody().getFirstChild().appendChild(cddata);
// remove the text tag with the raw text that will be escaped
message.getSOAPBody().getFirstChild()
.removeChild(message.getSOAPBody().getFirstChild().getFirstChild());
}
} catch (Exception ex) {
// fail
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext soapMessage) {
return true;
}
@Override
public Set<QName> getHeaders() {
return Collections.EMPTY_SET;
}
}
这是一个简单的 class,我只有一个带有文本的标签,但在更复杂的情况下,您可以在 DOM.
中采取必要的操作
我有一个使用 CXF 生成的 jax-ws 客户端
请求有一个包含 xml 的字符串参数 (MGRequest),一切正常,但生成的请求是这样的:
<S:Body>
<ns5:MGRequest><mytag>hello</mytag></ns5:MGRequest>
</S:Body>
我需要像这样生成正文:
<S:Body>
<ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest>
</S:Body>
(因为我无法控制服务器..)
客户端就像一个标准的 jax-ws:
@WebService(name = "ServiceSoap")
@XmlSeeAlso({ ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ServiceSoap {
@WebMethod(operationName = "ProcessMessage")
@WebResult(name = "MGResponse")
public String processMessage(
@WebParam(partName = "input", name = "MGRequest") String input);
}
我这样称呼:
Service client = new Service(url);
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler()));
ServiceSoap service = client.getServiceSoap();
String msgToSend = JaxbUtil.jaxbObjToString(xmlObj, false);
String response = service.processMessage(msgToSend);
我尝试在 @WebParam
之前添加 @XmlJavaTypeAdapter(CDataAdapter.class)
但结果是:
<S:Body>
<ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest>
</S:Body>
其中 CDataAdapter:
public class CDataAdapter extends XmlAdapter<String, String> {
@Override
public String marshal(String v) throws Exception {
return "<![CDATA[" + v + "]]>";
}
@Override
public String unmarshal(String v) throws Exception {
return v;
}
}
知道如何存档吗? 谢谢
经过一个晚上的工作,我找到了解决方案:
像这样向客户端添加 javax.xml.ws.handler.Handler
:
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler(), new CDataHandler()));
我的 HandlerFactory 构建处理程序的位置:
public static HandlerResolver build(final Handler... handlers) {
return new HandlerResolver() {
@Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
if (handlers != null) {
for (Handler handler : handlers) {
handlerChain.add(handler);
}
}
return handlerChain;
}
};
}
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class CDataHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public void close(MessageContext context) {
}
@Override
public boolean handleMessage(SOAPMessageContext soapMessage) {
try {
SOAPMessage message = soapMessage.getMessage();
boolean isOutboundMessage = (Boolean) soapMessage
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// is a request?
if (isOutboundMessage) {
// build a CDATA NODE with the text in the root tag
Node cddata = (Node) message.getSOAPPart().createCDATASection(
message.getSOAPBody().getFirstChild().getTextContent());
// add the CDATA's node at soap message
message.getSOAPBody().getFirstChild().appendChild(cddata);
// remove the text tag with the raw text that will be escaped
message.getSOAPBody().getFirstChild()
.removeChild(message.getSOAPBody().getFirstChild().getFirstChild());
}
} catch (Exception ex) {
// fail
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext soapMessage) {
return true;
}
@Override
public Set<QName> getHeaders() {
return Collections.EMPTY_SET;
}
}
这是一个简单的 class,我只有一个带有文本的标签,但在更复杂的情况下,您可以在 DOM.
中采取必要的操作