part 远程调用 查询 getx 请求方式 方式 exception style
Webservice 是一套远程调用技术规范
远程调用 RPC, 实现了系统与系统进程间的远程通信. java 领域有很多可实现远程通讯的技术,如:RMI(Socket + 序列化)、Binary-RPC(Http + 二进制, 代表 Hessian)、XML-RPC(Http+XML, 代表 Burlap, WebService 用的 SOAP)、JMS(使用消息机制)、Mina(使用 NIO) 等, 底层都是基于 http/socket 和网络 IO 来实现的. 从效率上来讲, RMI > Hessian >> Burlap >> web service.
构成 webservice 的几个要素:
1.WSDL:web 服务描述语言. 即 webservice 服务的使用说明书, 自动生成,无需编写
通过访问类似 http://127.0.0.1:12345/weather?wsdl 的地址可以查看它长如下这样子, 阅读顺序从下往上
2.SOAP:简单对象访问协议 http post + xml 必有 envelope 标签,将 XML 文档标识为一条 SOAP 消息必有 body 标签,传输的信息 可选 header 标签,包含头部信息可选 fault 标签,提供有关在处理此消息所发生错误的信息
SOAP 常用有 1.1, 1.2 两个版本. jdk 的 Jaxws 只支持发布 SOAP1.1 服务.
如要 SOAP1.2 服务, 需要引入 jaxws-ri, [email protected](SOAPBinding.SOAP12HTTP_BINDING)3.UDDI:提供 webservice 服务的注册和搜索功能, 不实用
服务端
- public interface WeatherInterface {
- public String queryWeather(String cityName);
- }
- //实现类前加WebService注解//@BindingType(SOAPBinding.SOAP12HTTP_BINDING)@WebService
- public classWeatherImplimplements WeatherInterface {
- @Override
- public String queryWeather(String cityName) {
- String weather = "晴";
- return weather;
- }
- }
- public class WeatherServer {
- public static void main(String[] args) {
- //Endpoint发布服务, 参数1: 服务地址, 参数2: 服务实现类Endpoint.publish("http://127.0.0.1:12345/weather",new WeatherImpl());
- }
- }
对于定义的服务实现类, 可以用注解进行修饰
@WebService 定义服务,在类上边
targetNamespace:指定命名空间
name:portType 的名称
portName:port 的名称
serviceName:服务名称
endpointInterface:如果一个服务类实现了多个服务接口,但只需要发布一个接口的方法,可通过此注解指定要发布服务的接口
@WebMethod 定义方法,在方法上边
operationName:方法名
exclude:设置为 true 表示此方法不是 webservice 方法,不会发布,默认是 false
@WebResult 定义返回值,在方法返回值前边
name:返回结果值的名称
@WebParam 定义参数,在方法参数前边
name:指定参数的名称
客户端
首先, 用命令 wsimport -s . http://127.0.0.1:12345/weather?wsdl 生成支持类, 导入工程中
第一种使用方式 使用相关类
- public class Client1 {
- public static voidmain(String[] args)throws IOException {
- // WSDL的地址, 非服务地址URL url =newURL("http://127.0.0.1:12345/weather?wsdl");
- //创建服务名称
- //参数一: namespaceURI – WSDL文档中 types/targetNamespace
- //参数二: localPart - 服务视图名, WSDL文档中 service-nameQName qname =newQName("http://WebXml.com.cn/", "WeatherWS");
- //创建服务视图
- //参数1: wsdlDocumentLocation WSDL地址
- //参数2: serviceName 服务名称Service service = Service.create(url, qname);
- //获取服务类 getPort(WSDL文档中portType-name)WeatherWSSoap weatherWSSoap = service.getPort(WeatherWSSoap.class);
- //调用方法 WSDL文档中portType-operation-nameString result = weatherWSSoap.queryWeather("北京");
- System.out.println(result);
- }
- }
第二种使用方式 http 工具访问
- public class Client2 {
- public static voidmain(String[] args)throws IOException {
- // 服务地址URL url =newURL("http://127.0.0.1:12345/weather");
- // 创建连接对象HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- // 设置参数
- // Http发送方式:POST必须大写connection.setRequestMethod("POST");
- // content-typeconnection.setRequestProperty("content-type", "text/xml;charset=utf-8");
- // 设置输入输出,默认connection没有读写权限,connection.setDoInput(true);
- connection.setDoOutput(true);
- // 发送请求String soapXML = getXML("北京");
- OutputStream os = connection.getOutputStream();
- os.write(soapXML.getBytes());
- // 接收响应
- intresponseCode = connection.getResponseCode();
- if(200 == responseCode){
- InputStream is = connection.getInputStream();
- InputStreamReader isr =new InputStreamReader(is);
- BufferedReader br =new BufferedReader(isr);
- StringBuilder sb =new StringBuilder();
- String temp =null;
- while(null!= (temp = br.readLine())){
- sb.append(temp);
- }
- System.out.println(sb.toString());
- is.close();
- isr.close();
- br.close();
- }
- os.close();
- }
- // 组织SOAP数据
- public static String getXML(String cityName){
- String soapXML = ""
- +""
- +""
- +""
- +""+cityName+""
- +""
- +""
- +""
- +"";
- return soapXML;
- }
- }
第三种使用方式 浏览器访问
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <script type="text/javascript">
- function queryWeather() {
- var xhr = new XMLHttpRequest();
- xhr.open("post", "http://127.0.0.1:12345/weather", true);
- xhr.setRequestHeader("content-type","text/xml;charset=utf-8");
- //设置回调函数
- xhr.onreadystatechange=function(){
- if(4 == xhr.readyState && 200 == xhr.status){
- alert(xhr.responseText);
- }
- }
- //组织SOAP协议数据
- var soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- +"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
- +"<soap:Body>"
- +"<getWeatherInfo xmlns=\"http://WebXml.com.cn/\">"
- +"<cityName>"+document.getElementById("cityName").value+"</cityName>"
- +"<userID></userID>"
- +"</getWeatherInfo>"
- +"</soap:Body>"
- +"</soap:Envelope>";
- //发送数据
- xhr.send(soapXML);
- }
- </script>
- </head>
- <body>
- 天气查询:<input type="text" id="cityName"/> <input type="button" value="查询" onclick="javascript:queryWeather();"/>
- </body>
- </html>
CXF 是一个开源的 webservice 框架 CXF 支持 SOAP1.1/1.2,REST 协议 CXF 支持 XML,JSON(仅 REST 下) 的数据格式
服务端 JAX-WS 方式 (SOAP)
- //@BindingType(SOAPBinding.SOAP12HTTP_BINDING) 默认发布SOAP1.1, 该注解发布SOAP1.2
- @WebService
- public interface WeatherInterface {
- public String queryWeather(String cityName);
- }
- public classWeatherImplimplements WeatherInterface {
- @Override
- public String queryWeather(String cityName) {
- String weather = "晴";
- return weather;
- }
- }
- //与spring整合后可不要该类
- public class WeatherServer {
- public static void main(String[] args) {
- JaxWsServerFactoryBean jaxWsServerFactoryBean =new JaxWsServerFactoryBean();
- //设置服务接口jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class);
- //设置服务实现类jaxWsServerFactoryBean.setServiceBean(new WeatherImpl());
- //设置服务地址jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/ws/weather");
- //发布
- jaxWsServerFactoryBean.create();
- }
- }
与 web 整合, spring+CXFservlet 替代 WeatherServer 类
- <?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:jaxws="http://cxf.apache.org/jaxws"
- xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
- http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
- http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
- <!-- 服务实现类 -->
- <bean id ="weatherImpl" class="com.zx.server.WeatherImpl"/>
- <!-- 拦截器 --
- <bean id ="inIntercepter" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
- <bean id ="outIntercepter" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
- -->
- <!-- 方式1 用JaxWsServerFactoryBean发布SOAP协议的服务 -->
- <jaxws:server address="/weather" serviceClass="com.zx.server.WeatherInterface">
- <jaxws:serviceBean>
- <ref bean="weatherImpl"/> <!-- 实现类 -->
- </jaxws:serviceBean>
- <!-- 配置拦截器 --
- <jaxws:inInterceptors>
- <ref bean="inIntercepter"/>
- </jaxws:inInterceptors>
- <jaxws:outInterceptors>
- <ref bean="outIntercepter"/>
- </jaxws:outInterceptors>
- -->
- </jaxws:server>
- <!-- 方式2 用Endpoint发布SOAP协议的服务 -->
- <jaxws:endpoint address="/weather" implementor="com.zx.server.WeatherImpl"/>
- </beans>
endPoint 只支持发布实现类 JaxWsServerFactoryBean 还可以发布接口
web.xml
- 配置CXF的Servlet--><servlet><servlet-name>CXF</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>CXF</servlet-name><url-pattern>/ws/*</url-pattern></servlet-mapping>
客户端
首先, 类似 wsimport, 使用 CXF 下的 Wsdl2java 生成支持类, 导入工程中
- public class WeatherClient {
- public static void main(String[] args) {
- JaxWsProxyFactoryBean jaxWsProxyFactoryBean =new JaxWsProxyFactoryBean();
- //设置服务接口jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class);
- //设置服务地址jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:12345/ws/weather");
- //获取服务接口, 可与spring整合替代WeatherInterface weatherInterface = jaxWsProxyFactoryBean.create(WeatherInterface.class);
- //调用查询方法String weather = weatherInterface.queryWeather("保定");
- System.out.println(weather);
- }
- }
与 spring 整合后由 spring 生成 weatherInterface 实例
- <!-- 用JaxWsProxyFactoryBean建立客户端 -->
- <jaxws:client id="weatherClient" address="http://127.0.0.1:12345/ws/weather"
- serviceClass="com.zx.WeatherInterface" />
服务端 JAX-RS 方式 (REST 风格)
基础 bean
- @XmlRootElement(name = "student") //能被格式化为XML
- public class Student {
- private long id;
- private String name;
- private Date birthday;
- public getXXX(),
- setXXX(); // get set方法
- }
服务接口
- @WebService
- @Path("/student")//将请求路径"/student"映射到接口上
- public interface StudentInterface {
- @POST // 指定请求方式 GET / POST@Produces(MediaType.APPLICATION_XML)//指定服务数据类型 XML / JSON@Path("/query/{id}")//将请求路径/query映射到方法上,[email protected]
- publicStudent query(@PathParam("id")long id);
- @GET
- @Produces({"application/json;charset=utf-8",MediaType.APPLICATION_XML})//同时指定json和xml, 添加访问参数?_type=json返回json; 添加?_type=xml返回XML@Path("/queryList/{name}")
- publicList queryList(@PathParam("name")String name);
- }
服务实现, 仅举例
- public classStudentImplimplements StudentInterface {
- @Override
- publicStudent query(long id) {
- Student st =new Student();
- st.setId(110);
- st.setName("张三");
- st.setBirthday(new Date());
- return st;
- }
- @Override
- publicList queryList(String name) {
- Student st =new Student();
- st.setId(110);
- st.setName("张三");
- st.setBirthday(new Date());
- List list = newArrayList();
- list.add(st);
- return list;
- }
- }
发布
- public class StudentServer {
- public static void main(String[] args) {
- //JAXRSServerFactoryBean 发布REST的服务JAXRSServerFactoryBean jaxRSServerFactoryBean =new JAXRSServerFactoryBean();
- jaxRSServerFactoryBean.setServiceBean(new StudentImpl());
- jaxRSServerFactoryBean.setResourceClasses(StudentImpl.class);
- jaxRSServerFactoryBean.setAddress("http://127.0.0.1:12345/ws/user");
- jaxRSServerFactoryBean.create();
- }
- }
与 web 整合, spring+CXFservlet 替代 StudentServer 类
- <?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:jaxws="http://cxf.apache.org/jaxws"
- xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
- http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
- http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
- <!-- 配置服务实现类 -->
- <bean id = "studentImpl" class="com.zx.StudentImpl"/>
- <!-- 使用JAXRSServerFactoryBean发布REST的服务 -->
- <jaxrs:server address="/user">
- <jaxrs:serviceBeans>
- <ref bean="studentImpl"/>
- </jaxrs:serviceBeans>
- </jaxrs:server>
- </beans>
web.xml
- 配置CXF的Servlet--><servlet><servlet-name>CXF</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>CXF</servlet-name><url-pattern>/ws/*</url-pattern></servlet-mapping>
REST 风格下 WSDL 访问网址为 http://127.0.0.1:12345/ws/user?_wadl
Webservice 与 CXF 框架快速入门
来源: http://www.bubuko.com/infodetail-2014408.html