WebService
完好格式见:https://www.zybuluo.com/Spancymath/note/1623555
什么是WebService?
基于web的服务,使用Web(HTTP)方式,接收和响应外部系统的某种请求,从而实现远程调用。
名词解释
- XML: Extensible Markup Language - 扩展性标记语言
用于传输格式化数据 - WSDL: WebService Description Language - Web服务描述语言
通过XML形式说明服务在什么地方
通过XML形式说明服务提供什么样的方法 - SOAP: Simple Object Access Protocol - 简单对象访问协议
SOAP = 在HTTP的基础上+XML数据
组成:Envelope(必须)+ Headers(可选)+ Body(必须)
在Java项目中发布WS服务
- 在类上添加@WebService注解
- 通过EndPoint发布一个WebService
a.给类添加@WebService注解后,类中的所有非静态、非final方法都将会对外公布
b.如果不希望某个方法不对外公开,可以在方法上添加@WebService(Exclude=true)
//1、添加注解
@WebService
public class OneService {
//2、至少包含一个可以对外公开的服务
public String sayHello(String name){
System.err.println("invoke "+name);
return "Hello "+name;
}
public static void main(String[] args) {
//3、第一个参数称为Binding即绑定地址,
//第二个参数是实现者,即谁提供服务
Endpoint.publish("http://localhost:9999/one", new OneService());
}
}
//4.在IE地址栏输入以下地址访问说明文件:
http://localhost:9999/one?wsdl
通过wsimport生成本地代码
常用参数为:
-d<目录> - 将生成.class文件。默认参数。
-s<目录> - 将生成.java文件。
-p<生成的新包名> -将生成的类,放于指定的包下。
(wsdlurl) - http://server:port/service?wsdl,必须的参数。
示例:
C:/> wsimport –s . http://192.168.0.100/one?wsdl总结
WebService和Web服务器的区别:WebService是Web服务器的应用,Web服务器是WebService运行所必须的容器。
WebService其内部是通过Socket实现的。
WebService的特点:
- WebService通过HTTP POST方式接受客户的请求
- WebService与客户端之间一般使用SOAP协议传输XML数据.
- 它本身就是为了跨平台或跨语言而设计的。
客户端调用WebService
- 通过wsimport生成客户端代码
- 通过客户端编程的方式调用
- 通过ajax调用 (js+XML)
var xhr = new XMLHttpRequest();
function sedAjax() {
var url = "http://localhost:8081/hello";
var nameText = document.getElementById("name").value;
var request = "" +
"" +
"" + nameText + " ";
$.ajax({
url: url,
type: "post",
contentType: "application/soap+xml;charset=utf-8",
data: request,
success: function (data) {
alert($(data).find("return").text());
}
})
}
- 通过URLConnection调用
SOAP请求过程分析
- 使用get方式获取wsdl文件,称为握手。
对于JDK1.6生成的ws服务,由于内部有一两个配置文件,所以会发出两次get请求。其他的一般为一次。 - 用户发出请求将使用post方式。
- 服务器响应成功。
CXF
- 使用ServerFactoryBean发布应用
- 使用CXF发布一个服务,与JDK6发布一个服务完全不同
即使是不使用@WebService注解,一样可以发布成功
即使此类没有对外公布的方法一样可以发布成功
public class CxfServer1 implements ICxfServer1 {
public String sayHi(String name) {
return "Hello " + name;
}
public static void main(String[] args) {
//声明实例,使用ServerFactoryBean发布服务
//使用CXF发布一个服务,与JDK6发布一个服务完全不同
//* 即使是不使用@WebService注解,一样可以发布成功
//* 即使此类没有对外公布的方法一样可以发布成功
ServerFactoryBean bean = new ServerFactoryBean();
//绑定到发布地址的端口
bean.setAddress("http://localhost:8080/cxf");
//设置服务接口,如果没有接口,则为本类
bean.setServiceClass(ICxfServer1.class);
//设置接口实现类,即服务类
bean.setServiceBean(new CxfServer1());
//发布服务
bean.create();
System.err.println("启动成功");
}
}
- 使用JaxWsServerFactoryBean(建议使用此类)发布应用
- JaxWsServerFactoryBean是ServerFactoryBean的子类,也是功能扩展类。
- 但在CXF的API文档中没有提供此类API,请通过查看源代码的方式获取此类的帮助。
- 此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不
出错,但也不会对外暴露任何方法。
使用此类生成的wsdl文件更加规范。
public class HelloImpl implements IHello {
@Override
public String sayHi(String name) {
System.out.println("syaHi called");
return "Hello2 " + name;
}
public static void main(String[] args) {
//使用jaxWs对其进行发布
JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();
//设置访问地址
bean.setAddress("http://localhost:8081/hello");
//注册服务接口
bean.setServiceClass(IHello.class);
//注册服务实现类
bean.setServiceBean(new HelloImpl());
//添加消息拦截器
bean.getInInterceptors().add(new LoggingInInterceptor());
bean.getOutInterceptors().add(new LoggingOutInterceptor());
//启动
bean.create();
System.out.println("服务启动完成...");
}
WebService-CXF-Spring基于web的cxf
- 由于cxf的web项目已经集成了Spring所以,cxf的服务类都是在spring的配置文件中完成的。以下是步骤:
- 第一步:建立一个web项目。
- 第二步:准备所有jar包。将cxf_home\lib项目下的所有jar包全部copy到新项目的lib目录下,里面已经包含了spring3.0的jar包。
- 第三步:在web.xml中配置cxf的核心servlet,CXFServlet。
cxf
org.apache.cxf.transport.servlet.CXFServlet
1
cxf
/ws/*
- 第四步:创建(最好是Copy)cxf-servlet.xml文件。这是一个spring的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
生成客户端代码遇到的问题
元素类型 * 必须后跟属性规范 ">" 或 "/>"
控制台报错,是xsd文件中有错,通过百度得知问题可能是缺少空格,但在xsd文件中没有找到有该问题的地方。进而查看wsdl文件,确实存在此类问题。
查看是否存在
#在editPlus中,开启正则表达式,搜索如下字符串
"\S*=
查到匹配的内容则有问题。
我的有问题的都是如下的内容(前后字符省略了)
"type="
全局替换"type="为" type=",问题解决
undefined simple or complex type 'ns1:string'
这个问题,在wsdl中添加
由于公司内网,该网址访问不了,所以直接用浏览器打开网址,保存内容到encode_schemas.xml,改上边引入为
XmlElementRef中没有required属性
生成的java文件导入idea,报XmlElementRef中没有required属性
此问题更改生成命令即可
wsdl2java -verbose -frontend jaxws21 -client Service.wsdl
去除JAXBElement引起的混乱代码
如下博客解决JAXBElement引起的混乱代码
https://blog.csdn.net/bob007abc/article/details/8599685