产品 webservice 接口——关于带特殊字符的报文接收报错的处理

产品 webservice 接口——关于带特殊字符的报文接收报错的处理

@author:​$\textcolor{Tan}{donnie}$
产品应用示例:拦截器处理特殊字符可配置化​
  • 配置表

image.png
* 拦截器配置文件:unimax-a-webservice.xml

 <!-- 输入日志拦截器 -->  
 <bean id="xmlPreHandleInterceptor" class="com.epichust.project.utils.XmlPreHandleInterceptor" />  
   
 <jaxws:endpoint id="erpWebService"implementor="com.epichust.fps.project.webService.server.impl.ErpWebService" address="/erpWebService">  
 <!-- 输入日志拦截器 -->  
 <jaxws:inInterceptors>  
 <ref bean="xmlPreHandleInterceptor"/>  
 </jaxws:inInterceptors>  
 </jaxws:endpoint>  
​  
​  
</beans>
  • 拦截器定义:XmlPreHandleInterceptor.java
package com.epichust.project.utils;  
​  
import cn.hutool.core.util.StrUtil;  
import com.epichust.mestar.logging.MestarLogger;  
import com.epichust.mestar.management.manager.ISysParamManager;  
import com.epichust.mestar.utils.spring.SpringContextHolder;  
import org.apache.commons.lang3.StringUtils;  
import org.apache.cxf.binding.soap.SoapMessage;  
import org.apache.cxf.helpers.IOUtils;  
import org.apache.cxf.interceptor.Fault;  
import org.apache.cxf.io.CachedOutputStream;  
import org.apache.cxf.message.Exchange;  
import org.apache.cxf.phase.AbstractPhaseInterceptor;  
import org.apache.cxf.phase.Phase;  
import org.apache.cxf.service.Service;  
import org.apache.cxf.service.invoker.MethodDispatcher;  
import org.apache.cxf.service.model.BindingOperationInfo;  
​  
import java.io.*;  
import java.lang.reflect.Method;  
public class XmlPreHandleInterceptor extends AbstractPhaseInterceptor<SoapMessage>  
{  
 public XmlPreHandleInterceptor() {  
 //这儿使用pre_stream,意思为在流关闭之前  
 super(Phase.PRE_STREAM);  
 }  
​  
 public void handleMessage(SoapMessage message) throws Fault  
 {  
 Boolean hasSrv = false;  
 String basePath = (String) message.get(SoapMessage.BASE_PATH);  
 ISysParamManager sysParamManager = SpringContextHolder.getBean("sysParamManager");  
 String svrList = sysParamManager.getSysParamValByCode(ApsProjectConstant.FPS_WEBSERVICE_SPECIAL);  
 if(StringUtils.isNotEmpty(svrList)){  
 for (String svrName : svrList.split(StrUtil.COMMA))  
 {  
 if(svrName.equals(StringUtils.substringAfterLast(basePath,"/ws/"))){  
 hasSrv = true;  
 break;  
 }  
 }  
​  
 if(hasSrv){  
 InputStream is = message.getContent(InputStream.class);  
 try  
 {  
 if (is != null)  
 {  
 String str = IOUtils.toString(is);  
 MestarLogger.debug("原格式--传入的xml格式为:" + str);  
 String splArrStr = sysParamManager.getSysParamValByCode(ApsProjectConstant.FPS_WEBSERVICE_SPECIAL_CHARACTERS);  
 if(StringUtils.isNotEmpty(splArrStr)){  
 for(String splChar:splArrStr.split(StrUtil.COMMA)){  
 String xmlColumnPre = StrUtil.addSuffixIfNot(StrUtil.addPrefixIfNot(splChar,"<"),">");  
 //转换的方式  
 str = str.replace(xmlColumnPre, StrUtil.addSuffixIfNot(xmlColumnPre,"<![CDATA["));  
 String xmlColumnSub = StrUtil.addSuffixIfNot(StrUtil.addPrefixIfNot(splChar,"</"),">");  
 str = str.replace(xmlColumnSub, StrUtil.addPrefixIfNot(xmlColumnSub,"]]>"));  
 }  
 }  
 MestarLogger.debug("处理后格式--传入的xml格式为:" + str);  
 InputStream ism = new ByteArrayInputStream(str.getBytes("UTF-8"));  
 message.setContent(InputStream.class, ism);  
 }  
 } catch (IOException e)  
 {  
 MestarLogger.error("WebService消息拦截器处理异常!", e);  
 }  
 finally  
 {  
 try  
 {  
 if (is != null)  
 {  
 is.close();  
 }  
 } catch (IOException e)  
 {  
 e.printStackTrace();  
 }  
 }  
 }  
 }  
}
  • 静态常量定义:ApsProjectConstant.java
package com.epichust.project.utils;  
​  
public class ApsProjectConstant  
{  
 /**接口特殊字符处理*/  
 public static final String FPS_WEBSERVICE_SPECIAL = "FPS_WEBSERVICE_SPECIAL";  
 public static final String FPS_WEBSERVICE_SPECIAL_CHARACTERS = "FPS_WEBSERVICE_SPECIAL_CHARACTERS";  
}  
​

【详细说明】CXF 拦截器—格式化请求和发送时的报文.pdf