java访问WebService接口

本文记录了使用Java访问WebService接口时遇到的问题,包括:1) Saaj识别Content-Type错误,通过切换SOAP版本或指定SoapAction解决;2) 服务器部署时的类库冲突和兼容性问题;3) 返回SOAP消息中的尖括号被转义,通过转换处理后解析;4) 编码问题,需要剔除非GB2312字符。文章提供了相应的解决方案和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间做一个用户接口,对方提供WebService方式的接口供调用,记录遇到的几个问题

1Soap1.1 Soap1.2 SoapAction

错误描述:用saaj访问axis2构建的WS,返回错误消息:

com.sun.xml.internal.messaging.saaj.soap.MessageImpl identifyContentType

严重: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message

com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: java.security.PrivilegedActionException: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:application/xml. Is this an error message instead of a SOAP response?

    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:146)

错误分析:返回的Soap消息的Content-Typeapplication/xmlsaaj不识别此

Content-Type,认为返回的不是Soap响应

原因:1) 客服端saaj能识别的Content-Typetext/xmlapplication/soap+xml

2)       axis2返回的为application/xml,之所以返回此类型,是因为axis2根据请求类型返回不同Content-Type的内容,请求类型有soap1.1soap1.2REST

3)       客户端发送请求时,发送soap1.1但是代码里MIME头未加SoapAction设置,axis2是通过SoapAction的指定区分Soap1.1REST请求,这样请求被识别为REST,返回的content-tyee被设置为application/xml

解决方法:

1) 使用soap1.2

       MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL)

2) 使用soap1.1并指定SoapAction

           MessageFactory mf = MessageFactory.newInstance();

SOAPMessage msg = mf.createMessage();

msg.getMimeHeaders().addHeader("SOAPAction", Qns);

*   REST(Representational State Transfer): 表现性状态传输,soap区别在于,提交请求直接用url+参数,返回结果为xml文档,不使用soap消息作为往返的信息载体,说是不只将http协议作为单纯的传输协议什么的,第一次听说这个概念,但实际上以前做Domino的时候经常用到,类似?readviewentries这样的扩展Url命令

*   不单是axis2,只要使用soap1.1,Soap请求消息的SoapAction都是必须指定的,否则会出错,SoapAction的值可以从服务的wsdl文档中查

2、部署碰到的问题

错误描述:本地测试通过,部署到服务器上出错

1)    报不认SOAPConstants.SOAP_1_2_PROTOCOL常量,改成MF.newInstance()通过,可能和2)问题的原因一样

2)    我想用的是Javax.xml.soap包下的类,但是似乎在服务器上执行都被识别指向成了org.apache.axis下的一些类而报异常,发现服务器以前有部署axis,把相关的包从服务器上删掉,并拷入sunsaaj相关的几个包,问题解决,网络上说jdk1.5以上直接支持saaj,是不是不要拷sunsaaj包可以直接用?

3、返回Soap消息处理

错误描述:测试时发现,返回的Soap消息,业务标签的尖括号都被转义,类似于:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<soap:Body>

<GetUserByUnitResponse xmlns="http://aaaa/aa">

<GetUserByUnitResult>

&lt;Users&gt;

&lt;User&gt;

&lt;Id&gt;00001&lt;/Id&gt;

&lt;Name&gt;admin&lt;/Name&gt;

&lt;/User&gt;

……

&lt;Users&gt;

</GetUserByUnitResult>

</GetUserByUnitResponse>

</soap:Body>

</soap:Envelope>

 

这样我无法解析xml,业务数据都被作为一整个文本内容了,交涉很久,接口厂家称他那头没有问题,我也找不出这样的原因所在(我还是认为问题出在他那头(.net),那位高手指点下?),只能认命,先处理标签再用dom解析

处理代码

/**

     * 转换Soap消息,因返回的Soap内部业务标签都被转义,需进行处理

     * @param smsg SoapMessage对象

     * @param tempfilepath 临时文件名称

     * @return Document 处理后的Soap消息的Document对象

     * @return

     */

    public static Document TransformSoapmsg(SOAPMessage smsg,

           String tempfilepath) {

       Document document = null;

       try {

           File file = new File(tempfilepath);

           OutputStream out = new FileOutputStream(file);

           smsg.writeTo(out);

           out.flush();

           out.close();

           FileInputStream reader = new FileInputStream(file);

           InputStreamReader inr = new InputStreamReader(reader, "utf8");

           BufferedReader br = new BufferedReader(inr);

           String s1 = null;

           //逐行替换

           String regEx = "&lt;";

           String regEx2 = "&gt;";

           Pattern p = Pattern.compile(regEx);

           Pattern p2 = Pattern.compile(regEx2);

           String Strall = "";

           while ((s1 = br.readLine()) != null) {

              Matcher m = p.matcher(s1);

              String s = m.replaceAll("<");

              Matcher m2 = p2.matcher(s);

              String s2 = m2.replaceAll(">");

              Strall += s2 + "/r/n";

           }

           br.close();

           reader.close();

           // 打开源文件,将修改后的字符串写回去

           OutputStreamWriter outr = new OutputStreamWriter(

                  new FileOutputStream(tempfilepath), "utf8");

           BufferedWriter bw = new BufferedWriter(outr);

           bw.write(Strall);

           bw.flush();

           bw.close();

           DocumentBuilderFactory factory = DocumentBuilderFactory

                  .newInstance();

           DocumentBuilder builder = factory.newDocumentBuilder();

           document = builder.parse(new File(tempfilepath));

       } catch (Exception e) {

           e.printStackTrace();

       }

       return document;

    }

4、编码处理

问题描述:本地用户接口部分用户无法注册成功,经检查,只支持GB2312字符集,需要剔除用户名、部门名中的不支持字符。

     /**

     * 删除字符串中非GB2312字符

     * @param sourceStr  源字符串

     * @return 仅由GB2312字符组成的字符串

     */

    public static String delUnsupporGBKStr(String sourceStr) {

       String ret = "";

       String tmp = "";

       int k = 0;

       try {

           for (int i = 0; i < sourceStr.length(); i++) {

              //

              tmp = bytesToHexString(sourceStr.substring(i, i + 1).getBytes("gbk"));

              k = Integer.parseInt(tmp,16);

              if (k < Integer.parseInt("7E", 16)) {

                  ret += sourceStr.substring(i, i + 1);

              } else {

                  int c1 = Integer.parseInt(tmp.substring(0,2),16);

                  int c2 = Integer.parseInt(tmp.substring(2),16);

                  if (c1 >= Integer.parseInt("A1", 16)

                         && c1 < Integer.parseInt("F7", 16)

                         && c2 >= Integer.parseInt("A0", 16)

                         && c2 < Integer.parseInt("FF", 16)) {

                     ret += sourceStr.substring(i, i + 1);

                  } else {

                     System.out.println(sourceStr.substring(i, i + 1));

                  }

              }

           }

       } catch (Exception e) {

           System.out.println(e);

       }

       return ret;

    }

    /**

     * 字节数组转化为16进制数文本

     * @param bArray  字节数组

     * @return 16进制数文本 eg:“F0F2”

     */

    public static final String bytesToHexString(byte[] bArray) {

       StringBuffer sb = new StringBuffer(bArray.length);

       String sTemp;

       for (int i = 0; i < bArray.length; i++) {

           sTemp = Integer.toHexString(0xFF & bArray[i]);

           if (sTemp.length() < 2)

              sb.append(0);

           sb.append(sTemp.toUpperCase());

       }

       return sb.toString();

    }    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值