WebService是用来调用远程service的方法的。
Webservice需要远程发布必须jdk1.7及以上版本
我们要发布远程方法需要Endpoint这个抽象类 但是它有静态方法 利用他的静态方法publish进行发布
实现类还需要用注解@WebService来表示这个类是远程发布的类 方法要用@WebMethod注解
创建远程连接的类
package cn.et;
import javax.xml.ws.Endpoint;
public class TestJaxWS {
public static void main(String[] args){
/**
* 调用它的静态方法
*
* 第一个参数就是你发布远程能访问的 协议、地址、 端口
*
* 第二个参数是你需要发布的类
*/
Endpoint.publish("http://127.0.0.1:8888/test", new Animal());
}
}
实现类
package cn.et;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class Animal {
@WebMethod
public void run(){
System.out.println("动物在跑");
}
}
运行main发布 然后我们可以检查一下是否发布成功需要用我们的地址加上?wsdl http://127.0.0.1:8888/test?wsdl
访问出来是一个xml文件。
wsdl 是用来描述的 用来描述你的发布的方法有哪些
是WebService的描述语言 用户在网络上发布的web服务后不会告知第三方的具体实现
用户如果需要调用方法必须使用webservice发布方发布的地址?wsdl去查看
查看会得到一个xml文件 客服端就可以通过这个地址的xml文件生成调用的java代码
jdk就提供了将这种xml文件转成我们能够调用的java代码 命令如下
wsimport -d 生成调用方代码目录 -p 生成包名 -keep wsdl路径
-keep 表示要生成源码
提供方 提供一些方法 通过http协议暴露给调用方调用
调用方 通过wsdl地址解析被调用的方法信息从而调用方法
上面为提供方做的
调用方的使用
调用方我们来做一个关于手机号码归属地的查询
我们可以去web服务的一个网站去找我们需要的wsdl路径
wsimport -d "E:\weathWebService\src" -p cn.et.ws -keep http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
首先得到它提供的接口
生成成功后你的路径下面就会有一些类
测试类
package cn.et.ws.test;
import cn.et.ws.MobileCodeWS;
import cn.et.ws.MobileCodeWSSoap;
public class Test {
public static void main(String[] args) {
//找到提供的接口方法
MobileCodeWS mws = new MobileCodeWS();
//创建接口对象实际调用的发布方的实现类
MobileCodeWSSoap mcw = mws.getMobileCodeWSSoap();
//输入号码进行查询
String phon = mcw.getMobileCodeInfo("132******10", null);
//输出控制台
System.out.println(phon);
}
}
结果
Cxf
关于Cxf的一些使用
使用Cxf做一个发布者(提供方)
首先添加依赖
依赖
<!-- 定义的一个版本号 可以通过el表达式来取 -->
<properties>
<version>2.7.18</version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<!-- 上面定义了一个<properties></properties> 版本号-->
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${version}</version>
</dependency>
<!-- 日志打印log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
实现类
package cn.et.cxf;
/**
*计算机实现类
* */
public class CalcuServiceImpl implements CalcuService {
/* (non-Javadoc)
* @see cn.et.cxf.CalcuService#cal(int, int, java.lang.String)
*/
public String cal(int i,int j,String sign){
if(sign.equals("+")){
return (i+j)+"";
}else if(sign.equals("-")){
return (i-j)+"";
}else if(sign.equals("*")){
return (i*j)+"";
}else if(sign.equals("/")){
return (i/j)+"";
}
return "不在计算范围内";
}
}
暴露的接口
Endpoint时注解写在实现类中的 现在我们要写在接口中package cn.et.cxf;
import javax.jws.WebMethod;
import javax.jws.WebService;
/**
* 计算机接口
*
* Endpoint时注解写在实现类中的 现在我们要写在接口中
* */
@WebService
public interface CalcuService {
/**
* 两位数的简单计算机
* i 第一个数
* j 第二个数
* sign 表示使用什么进行运算
* */
@WebMethod
public abstract String cal(int i, int j, String sign);
}
发布类
package cn.et.cxf;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/**
*
* 发布类
*
* */
public class PubTest {
public static void main(String[] args) {
//借助对象用来发布
JaxWsServerFactoryBean jwfb = new JaxWsServerFactoryBean();
//设置地址
jwfb.setAddress("http://127.0.0.1:8888/calcu");
//设置调用方调用接口时 真实调用的方法 也就是实现类
jwfb.setServiceBean(new CalcuServiceImpl());
//设置暴漏的接口 这里必须有暴露的接口 我们之前用Endpoint时候可以不用。
jwfb.setServiceClass(CalcuService.class);
//发布出去 会返回service
jwfb.create();
}
}
使用Cxf做一个调用方
第一种方式
包路径和提供方的路径一致并且知道接口的情况下就可以使用这种方式
调用方知道接口
接口
package cn.et.cxf;
import javax.jws.WebMethod;
import javax.jws.WebService;
/**
* 计算机接口
*
* Endpoint时注解写在实现类中的 现在我们要写在接口中
* */
@WebService
public interface CalcuService {
/**
* 两位数的简单计算机
* i 第一个数
* j 第二个数
* sign 表示使用什么进行运算
* */
public abstract String cal(int i, int j, String sign);
}
调用方调用
package cn.et.cxf;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
/**
*
* 这种方式是我们知道接口之后我们就可以用这种方法。
*
* */
public class ReceTestInter {
public static void main(String[] args) {
JaxWsProxyFactoryBean jwfb=new JaxWsProxyFactoryBean();
//通过地址找到提供方
jwfb.setAddress("http://127.0.0.1:7878/calcu");
//设置暴漏的接口
jwfb.setServiceClass(CalcuService.class);
CalcuService ca=(CalcuService)jwfb.create();
String val = ca.cal(1, 2, "+");
System.out.println(val);
}
}
第二种方式就是之前的通过命令下载提供方提供的接口
Cxf也提供了和java一样的下载接口的命令
wsdl2java -d 生成的路径 -p 包名 wsdl地址
注意想直接用这个命令需要配置环境变量 不然要去命令的路径下执行此命令
wsdl2java -d "E:\CxfRece\src" -p cn.et.cxf.gen http://127.0.0.1:7878/calcu?wsdl
生成之后
然后我们可以通过不用Cxf的方式也能实现这个功能
package cn.et.cxf.gen;
public class Test {
public static void main(String[] args) {
CalcuServiceService css = new CalcuServiceService();
CalcuService cs = css.getCalcuServicePort();
String val = cs.cal(12, 13, "+");
System.out.println(val);
}
}
我们还可以通过远程只要知道wsdl地址 知道方法干什么用 知道传参就可以远程调用
测试类
package cn.et.cxf.invonk;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
/**
* 动态 只要知道wsdl地址 知道方法 参数就可以直接调用提供方提供的方法
*
* */
public class InvonkTest {
public static void main(String[] args) throws Exception {
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
//动态调用web服务 只需要知道 wsdl地址 方法名 传入的参数
Object[] result = client.invoke("getMobileCodeInfo", "13268506263",null);
System.out.println(result[0]);
}
}