当前位置 : 主页 > 网页制作 > Nodejs >

关于研究Webservice问题总结与心得体会

来源:互联网 收集:自由互联 发布时间:2021-06-24
关于研究Webservice问题总结与心得体会 一、问题描述分析 在前期我们调用edms系统中的webservice接口时,出现了问题。我们用了JDK Web服务API和第三方框架Axis1(Axis2)以及HttpClient等方式来

关于研究Webservice问题总结与心得体会

 

一、问题描述分析

    在前期我们调用edms系统中的webservice接口时,出现了问题。我们用了JDK Web服务API和第三方框架Axis1(Axis2)以及HttpClient等方式来连接webservice接口,最终均失败。在后台打印日志,错误描述如下:

java.io.IOException:Server returned HTTP response code: 401for URL: https://dms-test.sfchina.bmw.com.cn/FH/FileHold/UserRoleManager/WindowsLogin.asmx/Satsun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1626)
atsun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)    atClientTestTONet2.main(ClientTestTONet2.java:39)

在网上查阅,401错误是没有权限。这个问题困扰了我们很久,我们研究了webservice原理和尝试了多种访问Webservice的方式与写法,最终我们采用前端javascript中拼接SOAP消息的方式发送请求,用new ActiveXObject("Microsoft.XMLHTTP")这个异步对象传递消息;这样的话只要是域用户并已成功登录ARP系统,那么在edms系统中就会验证通过。最终解决了问题。

可是,我们用了两周的时间来解决这个问题,中间着实走了很多很多弯路。现在,回忆解决这一问题一路走来的历程,总结研究的思路。想一想我们研究的过程中那些走了弯路,哪些是当时没有考虑到的,哪些又是我们的想法的有偏差的,做一总结,以便以后遇到类似问题,或者其他的问题,吸取教训,总结经验,少走弯路,更能一步到位。

 

二、前期研究过程与结果

1.Axis1以及Axis2框架访问

首先,我们采用Axis框架访问webservice接口,关键调用实例如下:

Stringendpoint="https://dms-test.sfchina.bmw.com.cn/FH/FileHold/UserRoleManager/SessionManager.asmx/";   

Stringns="http://filehold.com/userrolemanager/sessionmanager/";

StringoperationName = "IsSessionValid";  

Serviceservice = new Service();  

Callcall = (Call) service.createCall();

call.setTargetEndpointAddress(endpoint);  

call.setOperationName(newQName(ns,operationName));        call.addParameter(newQName(ns,"sessionId"),org.apache.axis.encoding.XMLType.XSD_STRING,javax.xml.rpc.ParameterMode.IN);  

call.addParameter(newQName(ns,"keepAlive"),org.apache.axis.encoding.XMLType.XSD_BOOLEAN,javax.xml.rpc.ParameterMode.IN);  

call.setReturnClass(java.lang.String[].class); 

call.setUseSOAPAction(true);  

call.setSOAPActionURI(ns+"IsSessionValid"); 

res=(boolean)call.invoke(new Object[]{"200",true});

结果:出现问题401没有权限,不能访问。

分析:由于我们访问地址是由外网访问的,最终结果为401没有权限访问,可以看到我们访问的地址格式是https,当时我单纯的认为是由于访问https的地址,外网是没有权限。所以,我们又开始研究http和https访问的区别,现在回想起来,其实关键问题不在这里,在这里耽误了时间。不过,我们也很快证实了这一点。

2.Javaweb服务的API实现

使用基于底层java API的SOAP message的Web服务发送消息,关键代码如下:

URLurlTemp=new URL("http….");

URLConnectionconnection = urlTemp.openConnection();

connection.setDoOutput(true);

out =new OutputStreamWriter(connection.getOutputStream(), "UTF-8");

StringBuffersb = new StringBuffer();

sb.append("sessionId=1111&");

sb.append("keepAlive=true");

out.write(sb.toString());

out.flush();

StringsCurrentLine;

sCurrentLine= "";

InputStreaml_urlStream;

l_urlStream= connection.getInputStream();// 请求

BufferedReaderl_reader=newBufferedReader(newInputStreamReader(l_urlStream));

                while ((sCurrentLine = l_reader.readLine()) != null) {

                     sTotalString.append(sCurrentLine);

                }

                System.out.println(sTotalString);

               }

结果:依然报同样的401错误。

分析:由1和2的访问我们得出结论:

1)401权限的问题,关键不在于访问https这种格式,因为我们证实了用这种访问其他https格式的webservie接口,依然能成功。当时我们问题定位有误。耽误了些许时间。

2)由于这两种访问方式一种是由第三方框架Axis,另一种是有JAVA JDK自带的底层访问方式,我们测试过这两种方式访问其他的接口(例如天气遇到接口)均没有问题,可是我们链接edms系统webservice接口,是连不上的,没有权限访问。当时我认为,这两种写法是没有问题的。只要我们解决访问权限问题,并把验证用户的身份信息附到访问访问程序中,一切问题就解决。所以接下来,我们把重点放到权限这里。

    3.权限验证

   接下来,我们想着如何将身份用户信息提交到服务端,首先我们获得一个域用户,并成功登录ARP系统。接下来,我们用Axis1来访问,并附上登录用户信息,调用call.serUserName()和call.getMessageContext().setUsername(username),可是依然报401错误,后经过沟通知道,在.Net中提供了一个NetworkCredential类,通过它我们可以在网络中提供一个凭证,只有获得该凭证的用户才能访问相应的服务的权限。之后我又到网上查,尝试java.net.Authentucator、org.apach.axis2.transport.http.HttpTransportProperties.Authenticator,这些我们都一一试过,可都无济于事。

     其实,问题进展到这一步,我们能想到权限的问题,想到只有ARP的登录用户才能访问Edms的接口,经过查阅API文档我们获取的信息得知,edms系统会记录当前用户的sessionId这一关键信息,如果当初知识储备够丰富的话,我们就该考虑到用浏览器访问,完全用前端JavaScript访问webservice,这样才可以记录当前的用户信息,这样才能做到用户和edms中的联系,而非ARP的服务端与edms的联系。现在回想起来,我们在这里耗费了太多的时间。

4.HttpClient模拟浏览器访问接口。

    不过,我们在想到用js访问webservice之前,也在网上了解到使用httpclient4.*的包,用httpClient的方式模拟浏览器访问webservice,并试着在其中附用户权限,关键代码如下:
DefaultHttpClienthttpClient =newDefaultHttpClient();
httpClient.getParams().setParameter(HttpProtocolParams.HTTP_CONTENT_CHARSET,"utf-8");
NTCredentials  creds = newNTCredentials(username,password,myWorkStation,"");

我们采用拼soap协议的方式然后发送到webservice,

结果:在调用接口任无结果,报401无法访问。

分析:做到现在,我们已经确认两点:1)我们想要进入edms,必须在ARP中登录,该用户的信息才能通过验证。2)edms能记录用户的session,那么就说明我们用浏览器访问,这样的话,才能起到用户关联edms系统。

三、后期问题分析与结果

根据前期的分析,我们已确定以下两点:

1.根据Edms系统中要求访问者是已登录用户,我们必须在ARP系统中使用域用户单点登录成功,而且在edms系统中必须有该域用户的域信息,这样方可验证成功。(在前期我们联系IT部门已将axi1975用户设为域用户并拥有访问权限)。

2.根据接口API(FileHold)开发说明文档,edms会记录当前已用户的信息sessionid,那么我们只能采用浏览器的方式去请求webservice接口,这样,类似于通过浏览器自动记住当前已登录用户的身份信息,其中包括在后面通过调用webservice返回的sessionId值。

    显然,在java类中我们很难将身份信息提交到服务端,即使我们验证通过,那么当前用户的session怎么保存,怎么去控制它的失效时间。所以我们需要在浏览器中,用前端javascript中拼接SOAP消息的方式发送请求,用new ActiveXObject("Microsoft.XMLHTTP")这个异步对象传递消息;这样的话只要是域用户并已成功登录ARP系统,那么在edms系统中就会验证通过。

实例代码:
<script type="text/javascript">
 function RequestWebService() {
//这是我们在第一步中创建的Web服务的地址
var URL ="http://sccn0203/FH/FileHold/UserRoleManager/WindowsLogin.asmx";

vardata;
data = '<?xml version="1.0" encoding="utf-8"?>';
data=data+ '<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">';
data = data + '<soap12:Body>';
data = data + '<StartSessionxmlns="http://filehold.com/userrolemanager/windowslogin/">';
data = data + '<clientType>CustomClient</clientType>';
data = data + '</StartSession></soap12:Body>';
data = data + '</soap12:Envelope>';
//创建异步对象
 var xmlhttp = newActiveXObject("Microsoft.XMLHTTP");
xmlhttp.Open("POST", URL, false);
xmlhttp.SetRequestHeader("Content-Type","application/soap+xml");
xmlhttp.Send(data);

document.getElementById("data").innerHTML= xmlhttp.responseText;
//window.open('"http://sccn0203/FH/FileHold/WebClient/LoginForm.aspx?sessionId="+xmlhttp.responseText',"_blank");
}
</script>

四、解决问题与学习总结

     经过了两周的学习与研究,利用webservice连接edms接口,这一过程我们着实走了很多的弯路,也有一些认识上的错误和理解上的偏差:没有更仔细的研究开发API文档,所以没有能想到用浏览器前端访问webservice;没有更好的拓展自己的知识来解决问题,所以忽视了用JS来访问webservice的方式。这些疏忽和认识的错误,造成了很多时间和人力的浪费。所以,这是一次教训,总结经验,扩展知识面。如果以后遇到类似问题,我们能否少走弯路,甚至一步到位。

五、心得体会

    在开发webservice接口这一过程中,由于前期对webservice不够了解,所以刚开始研究其原理,掌握其用法。研究了两周由于权限问题被卡住,几乎没有进展。这也暴露出我的知识储备不够,在研究webservice知识时走马观花,没有系统全面的学习,导致没有想到用jS访问webservice。虽然进展不是很顺利,但最终解决了问题,最重要的是在这一过程中学到了很多。

1.遇到问题,一定要冷静的思考,想到问题点的入口后,继续往下钻,如果有进展,那继续研究;否则,迅速换一思路,寻找另一突破口。

2.在研究新的技术,要将该技术涉及相关的点都要了解到,想想如果自己早了解用JS访问webservice的话,可能就会少走一些弯路。

3.有的时候,询问别人也是一种方法。与别人分享自己的问题,看看别人是怎么想的,说不定你的问题别人也遇到过,他们的建议或许对自己有启发,比自己在那里独自思考可能会更好更快。

4.我们在研究一个问题时,如果自己花费了很多时间与精力在这个事情上,仍然没有解决问题,那么试着换一种思路,拓展知识面寻求其他办法,换一种思维或许会引刃而解。想想如果webservice这个问题继续按照我之前的写法与思路,也许再研究两周也没有什么进展。所以,接下来的学习中开阔知识面也很重要,

4.在编程方面,如果要测试某一功能的写法,在网络资料中找到相关代码demo,先全部Copy到环境中,确定成功执行的情况下,然后再根据自己的情况修改,这样可以减少很多不必要的错误。

5.要仔细阅读开发文档,如果我们仔细的阅读那个API文档,从中早一点发现并推敲上面的信息,或许我们能早一点找到用这一种方式去访问webservice。

6.成功=坚持冲过起步的低谷 + 良好的学习方法+ 勤敲代码的习惯 + 处理问题分析问题解决问题的能力

网友评论