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

WebService 四种发布方式总结

发布时间:2020-12-16 21:41:26 所属栏目:安全 来源:网络整理
导读:1.? CXF 方式 CXF 与 spring 搭建 webservice 是目前最流行的方式,但是传闻 cxf 与 jdk1.5 有些不兼容,我没有遇到过,我遇到的问题是 cxf 与 was6.1.1 不兼容,表现在 cxf 必须的 jar 包“ wsdl4j-1.6.2.jar”报错,报的错为: java.lang.IncompatibleClas

1.?CXF方式

CXFspring搭建webservice是目前最流行的方式,但是传闻cxfjdk1.5有些不兼容,我没有遇到过,我遇到的问题是cxfwas6.1.1不兼容,表现在cxf必须的jar包“wsdl4j-1.6.2.jar”报错,报的错为: java.lang.IncompatibleClassChangeError,明显的jar包不兼容问题,很是头痛,后来查找资料找到解决办法是,将上述jar包新建一个was共享库,可以解决,但是客户周经理不想用此种方式,因为需要修改was,于是改用了axis2方式,下文会介绍。该问题在此处做个记录,以后使用cxfwas的时候需要注意!!!

?

使用cxf+spring搭建WebService

第一步,添加jar包。此处需要注意,不同环境(tomcatwasjar也不一定相同,例如我本地cxf+spring只需要如下jar包:

而泰康的was环境则需要如下jar包:

明显的多了很多,原因应该是服务器jar包池的不同。根据错误提示缺什么补什么就可以了,注意jar包勿重复。

第二步,配置web.xml文件,如下(重要的地方已标记):

<context-param>

param-name>contextConfigLocation</param-value>classpath:/applicationContext.xml>

???listener>?????listener-class>org.springframework.web.context.ContextLoaderListener>

???<!-- Character Encoding filter -->

filterfilter-name>encodingFilterfilter-class>org.springframework.web.filter.CharacterEncodingFilterinit-param>encoding>UTF-8filter-mappingurl-pattern>/*servlet>

????????servlet-name>CXFServlet>??servlet-class>org.apache.cxf.transport.servlet.CXFServletload-on-startup>1>

????servlet-mapping>

???????????/webservice/*>

上述标记的地方,第一处是spring配置文件路径;第二出是wsdl地址内容;


第三步,编写接口类与实现类,注意注解

接口类

@WebService

public?interface?SendService {

boolean?sendOA(@WebParam(name="param")String param);

boolean?sendOrg(OrgEntity org);

}

实现类

@WebService(endpointInterface="com.service.SendService",serviceName="sendService")

class?SendServiceImpl?implements?SendService{

boolean?sendOA(String param) {

System.out.println("-------sendOA---------param:"+param);

if(param.equals("zhoujian")){

return?true;

}

falseboolean?sendOrg(OrgEntity org) {

System."-------sendOrg--begin-------");

return?true;

}

}

第四步Spring配置文件

<?xml?version="1.0"?encoding="UTF-8"?>

beans

xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:jaxws="http://cxf.apache.org/jaxws"

????xsi:schemaLocation="

??????http://www.springframework.org/schema/beans

??????http://www.springframework.org/schema/beans/spring-beans.xsd

??????http://cxf.apache.org/jaxws

??????http://cxf.apache.org/schemas/jaxws.xsd"import?resource="classpath:META-INF/cxf/cxf.xml"/>

????"classpath:META-INF/cxf/cxf-extension-soap.xml"/>

???"classpath:META-INF/cxf/cxf-servlet.xml"/>

??

???jaxws:endpoint?id="sendServie"?implementor=com.service.impl.SendServiceImpl"?

address=/sendServie"?/>

?

<!-- <jaxws:client id="sendServiceClient" serviceClass="com.service.SendService"

address="http://10.137.138.11:9080/Wb/webservice/sendServie?wsdl" ?/>-->

?

beans “jaxws:client”该标签可以不必写,访问时可以手动拼接该url

第五步,发布,直接部署到服务器,访问:

http://10.137.138.11:9080/Wb/webservice/sendServie?wsdl

2.?Xfire方式

据说xfire方式已经很老了,但个人感觉,xfire方式很简单且容易配置,不知为啥过时了,也没感觉cxfaxis2哪里先进,我当时卡在cxfwas搞不定时想尝试xfire方式被周经理给拒绝了。

Xfire方式发布webservice

第一步,添加jar包,如下:

第二步,修改web.xml文件

<servlet>

????<servlet-name>XFireServlet</servlet-name>

????<servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>

????<load-on-startup>0</load-on-startup>

??</servlet>

??<servlet-mapping>

????<servlet-name>XFireServlet</servlet-name>

????<url-pattern>/services/*</url-pattern>

??</servlet-mapping>

第三步,编写接口类

接口类:

public abstract interface IBankingService {

public abstract String transferFunds(String paramString1);

}

实现类:

public class BankingService implements IBankingService{

??public String transferFunds(String fromAccount)

??{

????return fromAccount+":ok";

??}

}

第四步,编写services.xml配置文件

WEB-INF目录下新建目录META-INF,在该目录下新建文件夹xfire,该目录下新建文件services.xml

beans?"http://xfire.codehaus.org/config/1.0"servicename>Bankingnamespace>mybankserviceClass>

com.mybank.xfire.example.IBankingService

implementationClasscom.mybank.xfire.impl.BankingService

第五步,发布,部署到服务器,访问url:

http://localhost:9080/Xfire/services/Banking?wsdl

3.?AXIS2方式

Axis2发布WebService有两种方式,其一是利用axis2插件打成aar包放到axis_war里面部署到服务器发布;其二是不打包发布(本例);我不清楚打包发布有什么好处,感觉很麻烦项目外还得部署一个war,现在介绍第二种不打包的方式,类似xfire,同时由于cxfwas不兼容导致wsdl.jar报错,但是xfireaxis2也用到wsdl.jar却不报错,我个人也是很费解,泰康项目目前使用的就是axis2方式。

Axis2发布WebService

很多是吧,不过都是从axis.war里面WEB-INF下的lib目录复制来的。

>AxisServlet>org.apache.axis2.transport.http.AxisServlet/services/*>

?

?


第三步,编写实现类

class?ServiceImpl {

public?String sayHello(String name){

System."================");

return?"hello:"+name;

}

}

第四步,增加WEN-INF内容

axis.war解压下的WEN-INF文件夹内的confmodules复制到项目WEB-INF

第五步,WEB-INF下创建文件夹services(名字不可改),在该目录下创建文件夹(名称随意),在该目录下创建文件夹META-INF(名称不可改),在该目录下创建文件services.xml(名称不可改),该文件内容为:

service?name="axisDemo"description>

????????Web Service例子

????parameter?"ServiceClass">

????????com.ServiceImpl

????parametermessageReceiversmessageReceiver?mep="http://www.w3.org/2004/08/wsdl/in-out"

????????????class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"?/>

????????"http://www.w3.org/2004/08/wsdl/in-only"

???????"org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"? 第六步,部署到服务器,发布URL为:

http://localhost:9080/Axis2Test/services/axisDemo?wsdl

4.?AXIS1方式

同上,不知道AXIS1哪里不好,配置也很简单,如下:

第一步,添加jar

第二步,修改web.xml

>

????????org.apache.axis.transport.http.AxisServlet

????>

??>/services/* 第三步,实现类与实体类

实现类:

package?com;

class?Axis {

"============:"+name);

"hi:"+name;

}

public?String sayHelloToUser(User u){

System."============:"+u.getId());

System."============:"+u.getPath());

System."============:"+u.getAdd());

"hi:"+u.getName();

}

}

?

?

实体类:

class?User {

private?String?id;

name;

add;

path;

????

????getter setter ……方法

?

第四步,创建配置文件:在WEB-INF下新建文件“server-config.wsdd”

deployment?"http://xml.apache.org/axis/wsdd/"

?????????xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"?<!--?globalConfiguration?标签内容为系统默认 无需更改à

?<globalConfiguration"adminPassword"?value="admin"/>

??"attachments.Directory"?"./attachments""attachments.implementation"

?????????????"org.apache.axis.attachments.AttachmentsImpl""sendXsiTypes"?"true""sendMultiRefs"?"sendXMLDeclaration"?"axis.sendMinimizedElements"?requestFlowhandler?type="java:org.apache.axis.handlers.JWSHandler""scope"?"session"handler"request""extension"?".jwr">

?</"LocalResponder"

??????????"java:org.apache.axis.transport.local.LocalResponder"/>

?"URLMapper"

??????????"java:org.apache.axis.handlers.http.URLMapper""Authenticate"

???"java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>

<!—service?标签是需要配置的?-à

name?url中需要的参数?-"axisTest"?provider="java:RPC"??allowedMethods?的value值是方法名 可以写*-à

??"allowedMethods"?"*"/>

—classNamevalue值是类路径-"className"?"com.Axis"—wsdlTargetNamespacewsdl文件中TargetNamespace的值-"wsdlTargetNamespace"?"http://service.impl.tdi.taikang.tivoli.ibm.com/"???此处很重要,若方法需要传实体类,则配置此处-à?

??beanMapping?qname="myNS:Userxmlns:myNS="urn:BeanService"?languageSpecificType="java:com.User"/>??

?>

默认-à

transport?"http""URLMapper""java:org.apache.axis.handlers.http.HTTPAuthHandler"transport"local"responseFlow"LocalResponder"deployment 第五步,部署,同上。

5.?AXIS1客户端调用

此处调用方式为axis1的调用,需要传递的参数可以是字符串或实体类,字符串方式:

Service?service?=?new?Service();

Call?call?= (Call) service.createCall();

//wsdl地址

call.setTargetEndpointAddress(new?URL(wsdlUrl));

//设定调用3分钟不返回则超时

call.setTimeout(new?Integer(180000));

//命名空间(wsdl文件中的targetNameSpace属性值)?以及方法名

call.setOperationName(new?QName("http://com",?"sayHello"));

//参数类型

call.addParameter("name",XMLType.XSD_STRING,ParameterMode.IN);

//返回值类型

call.setReturnType(XMLType.XSD_STRING);

//参数值

String retXML2 = (String) call.invoke(?new?Object[] {?"yczhang"?});

System.out.println( retXML2);

实体类方式(调用axis2的接口有点问题):

UserEntity userEntry =?new?UserEntity();

userEntry.setId("yczhang");

userEntry.setName("yczhang");

Service service =?new?Service();

Call call = (Call) service.createCall();

"sayHelloToUser"));

//注册SimpleObject的序列化类型

QName qn =?"urn:BeanService",0);">UserEntity");

call.registerTypeMapping(UserEntity.class,qn,?new?BeanSerializerFactory(UserEntity.new?BeanDeserializerFactory(UserEntity. //参数类型(可省略)

call.addParameter("requestParam",?org.apache.axis.encoding.XMLType.XSD_ANYTYPE,192);">XSD_BOOLEAN);

Boolean retXML1 = (Boolean) call.invoke(?new?Object[] {?userEntry?});

System.out.println( retXML1);

注意,实体类方式,当调用的是由axis2方式所发布的接口时,容易出现问题,表现在所传递的实体类的属性内容为null,但在该实体类内新建一属性传如该值时,却有值。应该是axis1axis2的不兼容问题。并且调用axis2的接口时,需要在客户端写出namespace,即:

//call.setOperationName(new QName("http://localhost:9080/WS_Axis/services/axisTest","sayHelloToUser"));

?

该种调用方式对于axis1的接口没问题。泰康项目最终使用的是axis1发布的接口,并使用该种方式调用的。

static?void?main(String[] args)?throws?ServiceException,MalformedURLException,RemoteException {

String wsdlUrl =?"http://localhost:9080/WS_Axis/services/axisTest?wsdl";

//实体类

User user =?new?User();

user.setId("1");

user.setAdd("test");

user.setName("test");

user.setPath("test");

Service service =?new?Service();

Call call = (Call) service.createCall();

call.setTargetEndpointAddress(new?URL(wsdlUrl));

????????//设定调用3分钟不返回则超时

call.setTimeout(//call.setOperationName(new QName("http://localhost:9080/WS_Axis/services/axisTest","sayHelloToUser"));

//注册SimpleObject的序列化类型urn:BeanServicewsdd文件内有配置)

QName qn =?"urn:BeanService",255);">"User");

call.registerTypeMapping(User.new?BeanSerializerFactory(User.new?BeanDeserializerFactory(User. ????????//方法名

call.setOperationName("sayHelloToUser");

????????//user”是接口服务端方法体中的实体类所声明的变量名(say(User user)

call.addParameter("userIN);

//返回值类型

call.setReturnType(XMLType.XSD_STRING);

System.out.println( call.invoke(?new?Object[] { user }));

}

6.?AXIS2客户端调用

所需jar包:

具体代码:

class?RPClient {

throws?AxisFault {

try?{

?????????????//实体类

UserEntity ue =?new?UserEntity();

ue.setId("123");

ue.setAddress("test");

ue.setMail("123");

ue.setName("yczhang");

RPCServiceClient client =?new?RPCServiceClient();

Options options = client.getOptions();

String url =?"http://localhost:9080/WS_Axis2/services/axisDemo?wsdl";

EndpointReference end =?new?EndpointReference(url);

options.setTo(end);

?

Object[] obj =?new?Object[] { ue };

Class<?>[] classes =?new?Class[] { Boolean.class?};

?????????????//命名空间 ?方法名

QName qname =?"sayHelloToUser");

System.out.println(client.invokeBlocking(qname,obj,classes)[0]);

}?catch?(AxisFault e) {

e.printStackTrace();

}

}

注意 该种方式缺点是客户端实体类路径即包名必须与服务端实体类路径相同!!!但该方式可以调任何方式编写的接口!!!!

7.?CXF客户端调用

使用axisaxis2客户端调用cxf接口会有问题,建议使用cxf自身客户端调用或者使用webservice Client?自动生成客户端方式

所需的jar包:

功能代码:

class?TT {

void?main(String[] args) {

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

Client client = dcf.createClient("http://10.137.138.11:9080/WS_CXF/webservice/sendServie?wsdl");

try?{

????????//此处http://service.com/需要指向接口路径而非实现类

System.out.println(client.invoke("http://service.com/",255);">"sendOA"),test")[0]);

}?catch?(Exception e) {

e.printStackTrace();

}

}

}

注意:若运行程序时报错“JAXB 2.0 API?…..?endorsed”则需要将以下jar包放入jdk libjre lib

重启exlipse即可。

8.?Web Service Client客户端调用

右键项目:

?

调用代码如下:

class?CXFClient {

throws?Exception,IllegalAccessException,InvocationTargetException {

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

Client client = dcf.createClient("http://localhost:9080/WS_CXF/webservice/sendServie?wsdl");

client.invoke("sendOA",255);">"aa");

}

}

(编辑:李大同)

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

    推荐文章
    站长推荐
    热点阅读