这几天,这处理Jaave Servlet调用WebService的时候,碰到返回值为空的问题,但是,新建的Java项目,使用同样的方法调用,缺能够返回正确的值。
Servlet中的代码:
package dbconn;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.List;
import java.util.Map;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.encoding.XMLType;
import org.apache.axis.Constants;
import org.apache.axis.client.*;
import org.apache.axis.client.Service;
import org.apache.axis.client.Call;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ReadPLCByAddress_servelet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session=request.getSession();
session.setMaxInactiveInterval(600);
request.setCharacterEncoding("UTF-8");
String isIP = request.getParameter("plcid").trim();
String isPort = request.getParameter("isport").trim();
String isAddress= request.getParameter("isAddress").trim();
String isstrMsg="Read OK";
StringBuffer sb=new StringBuffer("[");
try {
if (isIP=="" || isPort=="" || isAddress=="" ) {}
else {
InputStream is = getClass().getResourceAsStream("Webservice.properties");
Properties prop = new Properties();
prop.load(is);
String namespace = "http://tempuri.org/";// targetNamespace
String actionURI = "ReadPLCByAddress"; // Action路径
String op = "ReadPLCByAddress"; // 要调用的方法名
String url = prop.getProperty("Url").trim();
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new java.net.URL(url));
call.setUseSOAPAction(true);
// action url
call.setSOAPActionURI(namespace + actionURI);//这个soapaction网站上也有对照放进去就可以了
// 设置要调用哪个方法
call.setOperationName(new QName(namespace, op));
call.setEncodingStyle(null);
// 设置参数名称,具体参照从浏览器中看到的
// call.addParameter(new QName(namespace,"arg0"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
// call.addParameter(new QName(namespace,"arg1"),XMLType.XSD_INTEGER,ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
// call.addParameter(new QName(namespace,"arg2"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
// call.addParameter(new QName(namespace,"arg3"),XMLType.XSD_STRING, ParameterMode.INOUT); //chu参,这里要注意参数名一定和webservice上测试框的参数名一致
// call.addParameter(new QName(namespace,"arg4"),XMLType.XSD_STRING, ParameterMode.INOUT); //chu参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "PLC_IP"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "PORT"),XMLType.XSD_INTEGER, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "ADDRESS"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "strReadData"),XMLType.XSD_STRING, ParameterMode.INOUT); //chu参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "strMsg"),XMLType.XSD_STRING, ParameterMode.INOUT); //chu参,这里要注意参数名一定和webservice上测试框的参数名一致
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_BOOLEAN);
// call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
String strMsg="";
String strReadData="";
Boolean res = (Boolean)call.invoke(new Object[] {isIP,isPort,isAddress,strReadData,strMsg});
if (res==true) {
List lst=call.getOutputValues();
strReadData=lst.get(0).toString();
// System.out.println( "strReadData: " + strReadData);
// System.out.println( "result: " + res);
sb.append("{\"strReadData\": \""+strReadData+"\", " +
// "\"Machine_Desc\":\""+rs.getString("Machine_Desc")+"\", " +
"\"isstrMsg\":\""+isstrMsg+"\"}");
}
else {isstrMsg="Read Failed";
// List lst=call.getOutputValues();
// strReadData=lst.get(0).toString();
// System.out.println( " strReadData: " + strReadData);
sb.append("{\"strReadData\": \""+strReadData+"\", " +
// "\"Machine_Desc\":\""+rs.getString("Machine_Desc")+"\", " +
"\"isstrMsg\":\""+isstrMsg+"\"}");
}
}
sb.append("]");
String result =sb.toString();
System.out.println( "result: " + result);
response.setContentType("text/javascript");
response.getWriter().print(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
调试、运行的时候,提示错误,注释掉报错的代码,将参数和返回值打印到屏幕,发现返回值为null,如下图:result: null
但是,相同的调用代码,在Java 的项目中却能够得到返回值, Java项目中的代码:
package dbconn;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.List;
import java.util.Map;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.encoding.XMLType;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class ReadPLCByAddress {
public static void main(String args[]){
// 提供IP地址搜索WEB服务的URL
// String url =readData("Webservice.properties", "Url");
String url ="http://localhost:8082/OPC.asmx"; // 在浏览器中打开url,可以找到
//private String soapAction="http://WebXml.com.cn/getCountryCityByIp"
String namespace = "http://tempuri.org/";// targetNamespace
String actionURI = "ReadPLCByAddress"; // Action路径
String op = "ReadPLCByAddress"; // 要调用的方法名
// String city = "上海";//要传的参数变量
String isIP="192.168.1.80";
String isPort="9600";
String isAddress="DM.169";
String isValue="";
String isstrMsg="Write OK";
Service service = new Service();
try {
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(url));
call.setUseSOAPAction(true);
// action url
call.setSOAPActionURI(namespace + actionURI);//这个soapaction网站上也有对照放进去就可以了
// 设置要调用哪个方法
call.setOperationName(new QName(namespace, op));
call.setEncodingStyle(null);
// 设置参数名称,具体参照从浏览器中看到的
call.addParameter(new QName(namespace, "PLC_IP"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "PORT"),XMLType.XSD_INTEGER, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "ADDRESS"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "strReadData"),XMLType.XSD_STRING, ParameterMode.INOUT); //chu参,这里要注意参数名一定和webservice上测试框的参数名一致
call.addParameter(new QName(namespace, "strMsg"),XMLType.XSD_STRING, ParameterMode.INOUT); //chu参,这里要注意参数名一定和webservice上测试框的参数名一致
// call.addParameter(new QName(namespace, "theCityName"),XMLType.XSD_STRING, ParameterMode.IN); //入参,这里要注意参数名一定和webservice上测试框的参数名一致
// call.setReturnType(new QName(namespace, op), Vector.class); // 返回的数据类型
// Object[] params = new Object[] {city};
// 调用方法并传递参数
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_BOOLEAN);
String strMsg="";
String strReadData="";
Boolean res = (Boolean)call.invoke(
new Object[] {isIP,isPort,isAddress,strReadData,strMsg}
);
//res
//System.out.println( " strMsg: " + strMsg);
//System.out.println( " strReadData: " + strReadData);
//Map lstp=call.getOutputParams();
List lst=call.getOutputValues();
strReadData=lst.get(0).toString();
strMsg=lst.get(1).toString();
System.out.println("url:"+ url);
System.out.println("namespace:"+ namespace);
System.out.println("op:"+ op);
System.out.println("actionURI:"+ actionURI);
System.out.println("isIP:"+ isIP);
System.out.println("isPort:" + isPort);
System.out.println(" isAddress:" + isAddress);
System.out.println( " strReadData: " + strReadData);
System.out.println( " strMsg: " + strMsg);
System.out.println( " res: " + res);
//if (res==true) {
//isstrMsg=strMsg;
//isValue=strReadData;
//}
// else {isstrMsg="Write Failed"; }
//System.out.println( " strMsg: " + strMsg);
//System.out.println( " strReadData: " + strReadData);
// Vector v = (Vector) call.invoke(params);
// for (int i = 0; i < v.size(); i++)
// {
// System.out.println(v.get(i));
// }
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
这个问题折腾了我两天时间,最后在朋友的提示下,将aixs的包放到Tomcat的lib中,才得到解决。
原来,Java项目和Servelet的调用jar包的方法不一样,Servelet需要到Tomcat中才能找到相应的包: