加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

4.4Webservice

发布时间:2020-12-16 21:50:14 所属栏目:安全 来源:网络整理
导读:点击打开链接:个人笔记 包括的内容有: wb的发布和客户端的调用 免费web服务常用连接:http://www.webxml.com.cn/zh_cn/web_services.aspx 客户端调用网上服务的例子 分析rpc/document_ware/document_bare的不同的参数交互方式。 webserivce的其他数据格式
点击打开链接:个人笔记
包括的内容有:
wb的发布和客户端的调用
免费web服务常用连接:http://www.webxml.com.cn/zh_cn/web_services.aspx
客户端调用网上服务的例子
分析rpc/document_ware/document_bare的不同的参数交互方式。
webserivce的其他数据格式的传递与交互(date map Bean list String)。
wb的异常处理
1.: webservice中的名词介绍:
? 1.1:与WebServices 相关的 J2EE 技术称为 JWS(Java WebServices),
????? 其中含有 JAX-WS、JAX-RS、JAXB、JAXR、SAAJ、 StAX等技术。
? 1.2:xml:?? 可扩展性标记语言。
? 1.3:XSD:是指XML结构定义 ( XML Schemas Definition ), XML Schema 是DTD的替代品。XML Schema语言也就是XSD。
???????????????? XML Schema描述了XML文档的结构。一个XML Schema会定义:文档中出现的元素、文档中出现的属性、
???????????????? 子元素、子元素的数量、子元素的顺序、元素是否为空、元素和属性的数据类型、元素或属性的默认和固定值。
? 1.4:SOAP? 即 Simple Object AccessProtocol 也就是简单对象访问协议。因为 SOAP基于XML和HTTP ,
??????? 其通过XML 来实现消息描述,然后再通过 HTTP 实现消息传输。所以SOAP 是用于在应用程序之间进行通信的一种通信协议。
? 1.5:WSDL 即Web Services Description Language也就是 Web 服务描述语言。
?? ??? ? 是基于 XML的用于描述 Web 服务以及如何访问 Web 服务的语言。它里面定义了web服务所使用的方法、变量名、返回值、url
???????? 等。看WSDL这个文件时从下往上看。
?? 1.6:JAXB(Java API for XML Binding)即XML元素跟Java对象之间的绑定。JAXP(Java API for XML Processing)包括了对
???????? XML的解析、校验、查询、变换。JAXM(Java API for XML Messaging简称JAXM)是为Java平台上的应用程序定义的API,
?? ??? ? 用以通过XML(以及SOAP)发送和接收消息,支持同步消息和异步消息。SAAJ支持带附件的SOAP消息。SAAJ是JAXM下的一个
???????? 分支。
?? 1.7:jax-rpc/jax-ws/jax-rs
?? ??? ?支持 SOAP 的是JAX-RPC/JAX-WS方式,支持REST的是JAX-RS
2: webservice的实现方式: jax-ws/xfire/cxf/axis2等
3:? 发布一个最简单的webservie以及客户端的调用方式:
? ? 3.1 首先得创建发布一个webservice,先创建一个Java工程,在com.webservice这个包下创建一个接口FirstService并且在接口类名
?????? 前加上@WebService这个注解(表明这是一个Web服务接口)和在接口中定义一些方法。再在这个包里创建一个First实现类,实现的接
?????? 口为前面创建的接口。并且要在First类的前面加上@WebService(endpointInterface = "com.webservice.FirstService")来说
?????? 明它实现的服务接口类是哪个。结构是:
??????

??


?????


??????

????? Endpoint.publish(address,implementor);其中的address是webservice的访问地址,可以随意填写,第二个参数是new一个实
????? 现对象。访问的时候address加上?WSDL。
? 3.2: 客户端调用服务端: 有三种方式(1.代理模式2.sope消息的方式3.客户端桩的模式)
???? ??? 都得先创建一个Java工程名叫WebServiceClient01.
???? ??? 3.2.1:代理模式
???? ??? 先将服务端的接口类拷到客户端中。
??????

???????? 再写调用类:
?????

????? 3.2.2: 客户端桩的模式:通过WSDL地址,或者WSDL文件,生成客户端的调用类
?????? 一:使用MyEclipse工具来生成{内部调用jdk的命令}
? ? ?? 二:通过jdk自带的命令来生成。
?????? 二:通过jdk自带的命令来生成
???? ?? -d <directory>??????????? 指定放置生成的输出文件的位置
?????? ?-keep???????????????????? 保留生成的文件
???? ?? -p <pkg>????????????????? 指定目标程序包
???? ?? -verbose????????????????? 有关编译器在执行什么操作的输出消息
???? ??? 先在e盘建一个名叫test_service的文件夹,
???? ??? 再在jdk的目录下用命令行来运行总的执行命令是:
???? ??? D:jdkbin>wsimport -d E:test_service -p com.client -keep -verbose http://localhost:5050/first?wsdl
???????? 然后在到E:test_servicecomclient里把.class的都删了。再把com包整个拷到一个Java工程名叫WebServiceClient01里。
???????? 最后写调用类:??????? ???? ??
???????

?????? 一:使用MyEclipse工具来生成
???? ???? ??? 先在工程中建一个包名叫com.myeclipse,再在这个包上右键点击-->other-->Web Service Client点击后进行下一步下一
????? 步。??? ???
???????

???? ???? ?? 注意:生成客户端的时候,服务端一定要处于发布状态,不然可能会生成失败。
????????? 最后写调用类:??????
????????

??????? 3.3:发送原始的Soap消息:Http协议中,通过Soap协议来发送XML数据的消息格式。这种消息格式称为Soap消息。
???? ?? 3.4:还有其它两种
???? ???? ??? 1:利用开源的工具(CXF,AXis2)也提供相应的调用方法。
???? ???? ??? 2:Http协议中,通过Soap协议来发送XML数据的消息格式
?? ??????????????? 利用开源Commont-httpClient来模拟HTTP请求,发送XML的消息格式。
4:注解:
???? @WebResult(name="returnWord") 接口的返回值
@WebParam(name="cityName")接口的参数
????

5:免费web服务常用连接: http://www.webxml.com.cn/zh_cn/web_services.aspx
6:例子:客户端调用网上的服务
???? ??? 因为是调用网上的,所以用wsdl地址生成客户端时会有错,所以一般情况下都是用wsdl文件。
???? ??? 步骤:
???? ???? ???? ? 先建一个名叫wsdl的文件夹,再在这个文件夹里建一个带有.wsdl后缀的文件(chinese_to_english.wsdl)。
???? ???? ???? ?? 再把网上的那个wsdl地址里的内容复制到chinese_to_english.wsdl。
???? ???? ???? ?? 删除里面的中文描述和过时的标签。
???? ???? ???? ??? 最后像利用wsdl地址生成那样生成客户端文件。生成完后,wsdl文件夹就可以删了。
???? ???? ???? ??? 最后的最后就是写调用类啦!
?7:?分析rpc/document_ware/document_bare的不同的参数交互方式。
? ? ???? rpc:@SOAPBinding(style = SOAPBinding.Style.RPC)即远程调用模式,rpc没有bare模式。
?? ??? ?
?? ??? ?RPC模式下,方法中的参数与返回值,直接定义在message元素中。
?? ??? ?<message name="add">
?? ??? ??? ?<part name="x" type="xsd:int"/>
?? ??? ??? ?<part name="y" type="xsd:int"/>
?? ??? ?</message>
?? ??? ?<message name="addResponse">
?? ??? ??? ?<part name="addResult" type="xsd:int"/>
?? ??? ?</message>
?? ??? ?<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
?? ?
?? ??? document_bare:@SOAPBinding(style = SOAPBinding.Style.DOCUMENT,
?? ??? ??? ??? ? parameterStyle = SOAPBinding.ParameterStyle.BARE)

?? ??? ?注意点:bare模式下,webservice的方法只能有一个参数。

?? ??? ?Bare模式下,方法中的参数与返回值,直接在xsd文件中使用type来做声明。
?? ??? ?
?? ??? ?<message name="divide">
?? ??? ??? ?//name为方法参数的名称?? element为直接引用xsd中定义的元素。
?? ??? ??? ?<part name="x" element="tns:x"/>
?? ??? ?</message>
?? ??? ?<message name="divideResponse">
?? ??? ??? ?<part name="divideResult" element="tns:divideResult"/>
?? ??? ?</message>

?? ??? ?<xs:element name="divideResult" type="xs:int"/>
?? ??? ?<xs:element name="x" type="xs:int"/>

?? ?document_warpper:封装格式。message方法中可以传递多个参数。
?? ??? ?每一个参数都使用了封装类型。
?? ??? ?<xs:element name="add" type="tns:add" /> //tns:add又引用下面定义的complexType类型。
?? ??? ?? <xs:element name="addResponse" type="tns:addResponse" />
?? ??? ?? <xs:element name="divide" type="tns:divide" />
?? ??? ?? <xs:element name="divideResponse" type="tns:divideResponse" />

?? ??? ? <xs:complexType name="add">
?? ??? ??? ?<xs:sequence>
?? ??? ??? ??? ?<xs:element name="x" type="xs:int" />
?? ??? ??? ??? ?<xs:element name="y" type="xs:int" />
?? ??? ??? ?</xs:sequence>
?? ??? ? </xs:complexType>
8.webserivce的其他数据格式的传递与交互。
? ? ?日期类型/Bean/List/Map接口如何处理:
? ? ?日期类型:服务端是java中的日期类型。java.util.Date
? ?? Soap消息中传递是XML中的日期类型。XMLGregorianCalendar
? ?? XMLGregorianCalendar---->GregorianCalendar----->Date---->格式化成字符串。
? ? ?Map:服务端是Map类型,但是WSDL定义的是List类型。
? ?? 将Map做为WebSevice的数据传递时,不能再放入其他的复杂数据类型,如自定义的一些类型。
? ? ?注意:一般情况下我们不会使用这些复杂的类型,而是使用String这种基本的类型。
? ? ?8.1:日期类型:客户端测试代码:?

?package com.date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.datatype.XMLGregorianCalendar;

import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;

public class TestMain {
public static void main(String[] args) {
TestMain testMain = new TestMain();

// testMain.get();

testMain.set();
}

private void get() {
IDateService dateService = new DateImplService().getDateImplPort();
/**
* XML元素中的日历对象
*/
XMLGregorianCalendar xmlCalendar = dateService.getSysDate();
int year = xmlCalendar.getYear();
int month = xmlCalendar.getMonth();
System.out.println(year + "-" + month);
/**
* 转成java中的日历对象
*/
GregorianCalendar calendar = xmlCalendar.toGregorianCalendar();
Date date = calendar.getTime();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("接收服务端返回的日期 = " + dateFormat.format(date));

}

private void set() {
/**
* java中的日历对象
*/
Date date = new Date(2015-1900,6,7,11,12,14);
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(date);
/**
* 转为XML中的日历对象
*/
XMLGregorianCalendar xmlCalendar = new XMLGregorianCalendarImpl(
calendar);
IDateService dateService = new DateImplService().getDateImplPort();
dateService.setClient(xmlCalendar);

}
}
服务端实现类的代码:

package com.webservice;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.jws.WebService;

@WebService(endpointInterface = "com.webservice.IDateService")
public class DateImpl implements IDateService {

public Date getSysDate() {
Date date = new Date();
return date;
}

public void setClient(Date date) {

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String strTime = dateFormat.format(date);

System.out.println("接收到客户端传递的Date数据 = " + strTime);

}

}


8.2: 将Map做为WebSevice的数据传递时
? ? ?服务器端实现类的代码:
? ? ?
package sss.webservice;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.jws.WebService;
@WebService(endpointInterface = "sss.webservice.IMapService")
public class MapImpl implements IMapService {

@Override
public Map<String,Object> getMap() {
Map<String,Object> map = new HashMap<String,Object>();
map.put("key1","hahah");
map.put("key2",new Date());
return map;
}
@Override
public void setMap(Map<String,Object> map) {
if(map!=null){
Set<Entry<String,Object>> entries = map.entrySet();
for (Entry<String,Object> entry : entries) {
String keyString = entry.getKey();
Object object = entry.getValue();
System.out.println("从客户端发送过来的数据:"+keyString+" "+object);
}
}
}

}

? ?客户端测试类的代码:
package sss.Map;

import java.util.Date;
import java.util.List;
import java.util.Map;
import sss.Map.*;
import sss.Map.GetMapResponse.GetMapResult;
import sss.Map.GetMapResponse.GetMapResult.Entry;

public class TestMain {
public static void main(String[] args) {
TestMain testMain = new TestMain();
//testMain.get();
testMain.set();
}

private void get() {
IMapService iMapService = new MapImplService().getMapImplPort();
GetMapResult gMapResult = iMapService.getMap();
List<sss.Map.GetMapResponse.GetMapResult.Entry> list = gMapResult.getEntry();
for (Entry entry : list) {
String keyString = entry.getKey();
Object object = entry.getValue();
System.out.println("服务器端发来的数据:"+keyString + " "+object);
}
}

private void set() {
IMapService iMapService = new MapImplService().getMapImplPort();
SetMap.Map map = new SetMap.Map();
List<sss.Map.SetMap.Map.Entry> list = map.getEntry();
//注意每一个entry都得另外新创建,不然list里就只有一个entry
sss.Map.SetMap.Map.Entry entry = new sss.Map.SetMap.Map.Entry();
entry.setKey("key1");
entry.setValue("hahah");
list.add(entry);
sss.Map.SetMap.Map.Entry entry1 = new sss.Map.SetMap.Map.Entry();
entry1.setKey("time");
entry1.setValue(new Date());
list.add(entry1);
iMapService.setMap(map);
}
}

8.3: 将String做为WebSevice的数据传递时,可以把String封装成xml或json格式。
服务端代码:
package com.webservice;

import javax.jws.WebService;

@WebService(endpointInterface = "com.webservice.IStrService")
public class StrImpl implements IStrService {
//服务端的接口实现类
public String getXMLStr() {
StringBuffer xmlStr = new StringBuffer();
xmlStr.append("<root>");
xmlStr.append("<head>");
xmlStr.append("");
xmlStr.append("</head>");
xmlStr.append("<body>");
xmlStr.append("<userbean>");
xmlStr.append("<userid>1</userid><username>用户名</username>");
xmlStr.append("</userbean>");
xmlStr.append("</body>");
xmlStr.append("</root>");
return xmlStr.toString();
}

public void setStrList(String xmlStr) {
}

}

客户端代码:
package com.str;

import java.io.StringReader;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
//客户端测试类
public class TestMain {
public static void main(String[] args) {
TestMain.get();
}
private static void get() {
IStrService strService = new StrImplService().getStrImplPort();
String xmlStr = strService.getXMLStr();
System.out.println("xmlStr = " + xmlStr);
// 解析XML的字符串 Dom4j
try {
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(xmlStr));
Element userBean = (Element) document
.selectSingleNode("/root/body/userbean");
String userid = userBean.elementText("userid");
String username = userBean.elementText("username");
System.out.println(userid + "t" +username);
} catch (Exception e) {
e.printStackTrace();
}
}
}

注意: 解析XML的字符串时可以用dom4j,要记得拷相应的jar包。
9.异常处理:
?wsdl中会把编译异常当作消息来处理,而运行时异常则不当作消息来处理。
正规情况下我们是抛编译异常,但我们一般都是抛运行时异常,也就是让我们交互不成功,双方都报错。
WebService中的自定义异常时,一般继承Exception,不继承RunTimeException
原因:继承Exception,WebService会将异常在wsdl中定义为一个message.
出现异常时,会将异常封装成为一个Soap消息传递给客户端。客户端就会获取到异常消息。
继承RunTimeException:服务端会抛异常,客户端接到的不是具体的异常。
是Soap中默认的异常。SoapFaultException
服务端代码:
服务端接口
package sss.webservice;
import java.util.Date;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
//服务端接口
@WebService
public interface IExceptionService {
@WebResult(name = "addResult")
public int add(@WebParam(name = "x")int x,@WebParam(name = "y")int y)throws Exception;
@WebResult(name = "subResult")
public int sub(@WebParam(name = "x")int x,@WebParam(name = "y")int y)throws RuntimeException;
@WebResult(name = "divideResult")
public int divide(@WebParam(name = "x")int x,@WebParam(name = "y")int y)throws DivideException;
}

接口实现类
package sss.webservice;

import javax.jws.WebService;
//服务端接口实现类
@WebService(endpointInterface = "sss.webservice.IExceptionService")
public class ExceptionImpl implements IExceptionService {

@Override
public int add(int x,int y) throws Exception {
if(x == 0 || y == 0){
throw new Exception("Exception:add中的X或Y不能为0。。。");
}
else return x+y;
}

@Override
public int sub(int x,int y) throws RuntimeException {
if(x == 0 || y == 0){
throw new RuntimeException("RuntimeException:sub中的X或Y不能为0。。。");
}
else return x+y;

}

@Override
public int divide(int x,int y) throws DivideException {
if(x == 0 || y == 0){
throw new DivideException("DivideException:divide中的X或Y不能为0。。。");
}
else return x+y;
}

}

客户端测试类:
package sss.Exception;
//客户端测试类
public class TestMain {
public static void main(String[] args) {
TestMain testMain = new TestMain();
//testMain.add();
? //testMain.sub();
testMain.didv();
}

private void add() {
// 服务端没有异常
// 客户端:com.exception.Exception_Exception
//这种抛编译异常的方式结果是客户端和服务端交互成功,
//当服务端发生错误的时候,会把错误抛给客户端,所以导致最后服务端没有报错,而只有客户端报错。
//这种异常的使用只有常规的时候会使用,不然一般情况下是不会使用的。
IExceptionService iExceptionService = new ExceptionImplService().getExceptionImplPort();
try {
iExceptionService.add(0,10);
} catch (Exception_Exception e) {
System.out.println(e.getFaultInfo().getMessage());
e.printStackTrace();
}

}

private void sub() {
// 服务端的异常:java.lang.RuntimeException
// 客户端的异常:javax.xml.ws.soap.SOAPFaultException 交互不成功异常
//这种抛出运行异常的方式是使客户端和服务端交互不成功,
//并且告诉双方你们出错的原因
//我们普遍都是使用这种方式。
IExceptionService iExceptionService = new ExceptionImplService().getExceptionImplPort();
iExceptionService.sub(0,10);
}

private void didv() {
//和抛出编译异常的效果是一样的。
IExceptionService exceptionService = new ExceptionImplService()
.getExceptionImplPort();

try {
exceptionService.divide(1,0);
} catch (DivideException_Exception e) {
System.out.println(e.getFaultInfo().getMessage());
e.printStackTrace();
}

}
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读