jaxwsjaxrs规范的webservice客户端调用方式及soap安全验证Word格式.docx
《jaxwsjaxrs规范的webservice客户端调用方式及soap安全验证Word格式.docx》由会员分享,可在线阅读,更多相关《jaxwsjaxrs规范的webservice客户端调用方式及soap安全验证Word格式.docx(22页珍藏版)》请在冰点文库上搜索。
System.out.println(ms.helloWS("
suansuan"
));
}catch(MalformedURLExceptione){
e.printStackTrace();
第二种方式中,还可以直接创建了SOAP消息后使用dispatch便可以进行传递,通过extractConentAsDocument方法得到Document类型的返回值
参考网页:
3.使用ajax+xml+js的方式调用
具体使用方法,参考整理的ajax跨域文档
4.URLConnection方式
//服务的地址
//服务的地址
URLwsUrl=newURL("
88/webServiceWS/wsWSPort"
HttpURLConnectionconn=(HttpURLConnection)wsUrl.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("
POST"
conn.setRequestProperty("
Content-Type"
text/xml;
charset=UTF-8"
OutputStreamos=conn.getOutputStream();
//创建SOAPMessage
SOAPMessagemsg=MessageFactory.newInstance().createMessage();
SOAPEnvelopeenvelope=msg.getSOAPPart().getEnvelope();
SOAPBodybody=envelope.getBody();
//创建QName来指定消息中传递数据
QNameename=newQName("
"
HelloWS"
//<
nn:
addxmlns="
xx"
/>
SOAPBodyElementele=body.addBodyElement(ename);
ele.addChildElement("
arg0"
).setValue("
Stringsoap1=soap.toSoapString(msg);
os.write(soap1.getBytes());
InputStreamis=conn.getInputStream();
byte[]b=newbyte[1024];
intlen=0;
Strings="
"
;
while((len=is.read(b))!
=-1){
Stringss=newString(b,0,len,"
UTF-8"
s+=ss;
}
System.out.println(s);
is.close();
os.close();
conn.disconnect();
也是通过wsdl生成客户端程序后调用,至于soapheader的验证,使用map加入验证信息后验证
具体的操作,在我工作文档中,有一个短信平台接口文档有详细的xfire的使用过程,通用性不错
注意,以上关于soap信息,我是根据生成的本地调用类的注释,编写soap信息,此外可以直接使用String类型的字符串,只要你熟悉soap的格式,就可以手动编写传递的soap消息。
Soap协议的消息
JAX-WS规范是一组XMLwebservices的JAVAAPI,在JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。
JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。
JAX-WS也提供了一组针对底层消息进行操作的API调用,你可以通过Dispatch直接使用SOAP消息或XML消息发送请求或者使用Provider处理SOAP或XML消息。
SOAPHeader元素可包含有关SOAP消息的应用程序专用信息(比如认证、支付等)
SAAJ构建SOAP消息
范例:
//创建SOAPMessage
QNameename1=newQName("
HelloWS1"
wsWSService1"
//header的targetspace和方法,入口
SOAPHeaderheader=msg.getSOAPHeader();
SOAPHeaderElementhele=header.addHeaderElement(ename1);
hele.addChildElement("
name"
suan"
password"
njau1918121"
//@配置的参数
//ele.addChildElement("
SecondB"
33"
//msg.writeTo(System.out);
System.out.println(soap.toSoapString(msg));
Soap信息里面的参数配置:
这是本地生成的客户端信息,targetNamespace,@webParamarg0
QNameename=newQName("
这里面的三个数据,空间,方法名,服务名
参数名arg0
认识发布的webservice
Cxf框架:
其中wsWs是服务名,Hello是方法名,http:
//ws.webservice.suan/是定义的目标空间
单击,进入wsdl文档,
其中wsWSImplPort是进入的端口名
Jdk自带框架:
目标空间,方法名,端口名,服务名……都在了
注,了解发布的webservice,有助于创建soap信息
Webservice的加密的方案举例
(1)对webservice发布的方法,在入参中增加一个或多个字符串序列;
这里的字符串可以要求必须满足指定的格式,字符串可以再通过客户端传参数的时候加密,服务端解密;
扯点题外话,说起加密解密,我想起了页面级的自动登录功能,使用cookie保存密码,所谓的加密,是为了不让其他用户直接看到加密前的密码,而被直接通过登录功能登录。
那这一块接口的字符串加密的意义何在,我本来就是程序调用接口,不管加密不加密,还是一样的调用,又没有额外的客户端直接让你输未加密密码验证的(所以,以我现在的理解能力,觉得这个所谓的加密,除了能分辨使用对象之外,毫无安全性可言)
(2)对webservice发布的方法,入参中加上用户名和密码,然后服务端通过数据库校验;
参数中加入用户名和密码,验证不通过提示非法请求之类的,是一种方法
(3)对webservice发布的方法,通过handler/chain方式来实现验证(用户名&
密码校验/IP地址校验等);
主要讲这种常用的验证方式
参考网页cxf验证:
(4)对webservice发布的方法,采用webservice的users.lst来进行验证;
(5)对webservice发布的服务,通过servlet的Filter来实现验证;
(6)对webservice传输过程中的数据进行加密;
数据加密后,在服务器端解密
注:
关于axis框架下的两种验证方式参考网页
Axis框架下的handler验证:
Axis框架下的users.lst验证:
Webservice的安全机制Handler验证机制
WebService有两种安全机制,一是利用WS-Security将签名和加密头加入SOAP消息,另一个是利用数字证书和数字签名认证。
此篇文章介绍利用cxf实现WS-Security验证。
参考网页Cxf:
1.服务器端创建handler步骤,结合软件操作,免去注释的学习
本人通过myeclipse操作,只适用cxf框架开发的jax-ws规范的webservice,在**Impl.java右键jax-wstools----》createjax-wshandler
根据要求填写相关类,把验证类所需的handlerchain文件,建在webservice包下
新建完毕,一个是修改**Impl.java
原始的注入路径有问题
Handlers.xml文件内容如下:
<
handler-chainsxmlns="
xmlns:
xsi="
//www.w3.org/2001/XMLSchema-instance"
xsi:
schemaLocation="
<
handler-chain>
handler>
handler-name>
authHandler<
/handler-name>
handler-class>
suan.webservice.ws.AuthValidationHandler<
/handler-class>
/handler>
/handler-chain>
/handler-chains>
2.书写服务器端验证类:
根据soapheader里面的信息结构分两种处理方式
1.
SOAP-ENV:
Header>
authxmlns="
**namespace"
SOAP-ENV:
actor="
//www.w3.org/2003/05/soap-envelope/role/next"
>
name&
password//随意,可使用name|password,name-password
/auth>
//auth节点名称,可自定义suan,user...
/SOAP-ENV:
2.跟body中的结构一致
***xmlns:
wsWS="
arg0>
name<
/arg0>
//arg0可以自定义
arg1>
password<
/arg1>
***>
和
soap:
header>
authentication>
userorgid>
/userorgid>
UserOrgID
userid>
/userid>
Hubs1
userpsw>
/userpsw>
password
/authentication>
/soap:
先讲创建的区别:
QNameqname_user=newQName("
auth"
//auth
SOAPHeaderElementhelem_user=hdr.addHeaderElement(qname_user);
helem_user.addTextNode("
admin&
admin"
authentication"
helem_user.addChildElement("
userorgid"
userid"
***"
userpsw"
现在讲服务器端处理方式
针对第一种:
Booleanoutbound=(Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(!
outbound.booleanValue())
{
SOAPMessagesoapMessage=context.getMessage();
try{
SOAPEnvelopesoapEnvelope=soapMessage.getSOAPPart().getEnvelope();
SOAPHeadersoapHeader=soapEnvelope.getHeader();
if(soapHeader==null)generateSoapFault(soapMessage,"
NoMessageHeader..."
//报错
Iteratorit=soapHeader.extractHeaderElements(SOAPConstants.URI_SOAP_1_2_ROLE_NEXT);
if(it==null||!
it.hasNext())generateSoapFault(soapMessage,"
NoHeaderblockforrolenext"
//报错
Nodenode=(Node)it.next();
Stringvalue=node==null?
null:
node.getValue();
if(value==null)generateSoapFault(soapMessage,"
Noauthationinfoinheaderblocks"
//报错
//value就是获取到的header中的数据
}catch(SOAPExceptione){
e.printStackTrace();
}
}
第二种:
BooleanoutboundProperty=(Boolean)messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(!
outboundProperty){//InBoundMessage
StringuserOrgID="
StringuserID="
StringuserPSW="
SOAPMessagemessage=messageContext.getMessage();
try{
SOAPHeadersoapHeader=message.getSOAPHeader();
NodeListnodeList=soapHeader.getChildNodes();
//获取节点
for(inti=0;
i<
nodeList.getLength();
i++){
NodenodeAuth=nodeList.item(i);
if(nodeAuth.getNodeType()==Node.ELEMENT_NODE&
&
"
Authentication"
.equals(nodeAuth.getNodeName())){//判断节点名称,可以不判断,跟第一种一样
for(Nodenode=nodeAuth.getFirstChild();
node!
=null;
node=node.getNextSibling()){
if(node.getNodeType()==Node.ELEMENT_NODE){
if("
UserOrgID"
.equals(node.getNodeName())&
node.getFirstChild()!
=null){
userOrgID=node.getFirstChild().getTextContent();
}elseif("
UserID"
userID=node.getFirstChild().getTextContent();
UserPSW"
userPSW=node.getFirstChild().getTextContent();
}
}catch(SOAPExceptione){
log.warn(e);
thrownewRuntimeException(e);
以下是服务器端的具体实例,是第一种结构
publicclassAuthValidationHandlerimplementsSOAPHandler<
SOAPMessageContext>
{
publicSet<
QName>
getHeaders(){
//TODOAuto-generatedmethodstub
returnnull;
publicvoidclose(MessageContextcontext){
publicbooleanhandleFault(SOAPMessageContextcontext){
returnfalse;
publicbooleanhandleMessage(SOAPMessageContextcontext){
HttpServletRequestrequest=(HttpServletRequest)context.get(AbstractHTTPDestination.HTTP_REQUEST);
System.out.println("
客户端IP:
+request.getRemoteAddr());
Booleanoutbound=(Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
Iteratorit=soapHeader.extract