XML+HTTP风格架构和RESTful风格架构的webService
什么是webService
webService直译成中文是web服务,也就是将一组特定的功能发布到互联网上,供需要的程序使用。比如我们最常见的天气预报服务就是一种webService服务,在比如GoggleMap和BaiduMap提供的根据精度和纬度获取物理地址的服务也是webService。还有最重要的一点是webService是夸平台和语言的。
两个风格的webService服务
XML+HTTP风格的webService
这种风格的webService也叫做base webService,是最早出现和普遍使用的实现webService方案。是基于xml
和HTTP协议的,xml实现了跨平台和言沟通问题,http解决夸平台和语言传递消息。实现这种风格的webService有三个要素(发布一个webSservice SOAP和WSDL元素是必要的,UDDI是根据需要可选的):
- SOAP:简单对象访问协议,是交互数据的一种规范,是轻量级的、简单的、基于XML的,它被设计成在WEB上交换结构化的和固化的信息。
- WSDL:是一种描述webService服务的描述语言。简单的来说就是用一种固定的格式描述了webService有哪些服务,服务的入参和出参。这样我们发布一个webService服务,一些webService框架或者工具就能自动产生WSDL文件,客服端也可以根据WSDL文件生成访问服务器端的客户端代码。
- UDDI:是一种目录服务,是一种规范、是Web服务的注册和发现机制,可以使用它对 Web services 进行注册和搜索。UDDI,英文为 "Universal Description, Discovery and Integration",可译为“通用描述、发现与集成服务”。
RESTful架构的webService
关于RESTful在网上看了几篇文章,感觉理解不是一朝一夕就能理解透彻的,所有我也就不误导大家了,以下是我在网络上查看的几篇文章,感觉写的都不错,建议耐心的去看看,会有自己的一个初步理解。
http://www.ruanyifeng.com/blog/2011/09/restful.html
https://www.zhihu.com/question/28557115
我自己的理解:
RESTful架构的webService简单的来说,我们可以将程序的功能发布发布成网络的资源,客户端可以通过URI去访问这个资源,URI有四种请求方式GET、POST、PUT、DELETE四种方式,分别对应GET用来获取服务器资源、POST用于在服务器新建资源、PUT用于在服务器更新资源、DELETE用于在服务器删除资源,我们可以看出通过这四个请求方式可以对一个字资源进行原子操作,即CRUD(创建、读取、更新、删除)。例如:
GET请求http://localhost:8080/blog/user/query/10000表示获取id为10000的客户信息。
POST请求http://localhost:8080/blog/user/add表示添加客户信息,具有的客服信息在POST请求参数中。
PUT请求http://localhost:8080/blog/user/update/10000表示更新id为10000的客户信息
DELTE请求http://localhost:8080/blog/user/delete/10000表示删除id为10000的客户信息
我们通过以上四个URL可以观察出来:看到url就知道要什么、看到请求方式就知道干什么、看到http状态码就知道结果。我们也可把这种风格的URL称作为RESTful架构API。
java对两种风格的webService的支持
JAX-WS
JAX-WS:Java API for XML Web Services,是一组java接口,支持基于XML+HTTTP的WebService开发。JAX-WS是面向消息的,每次请求的时候指定了请求的方法,也就是对XML+HTTP风格的webService实现,具体框架框架:
CXF:Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持。
XFire:XFire是codeHaus组织提供的一个开源WebService框架。XFire在2007年后已停止更新。正式更名为Apache CXF,亦可以说是XFire2.0。
Axis:Axis是Apache组织推出的SOAP引擎。
JAX-RS
JAX-RS:Java API for RESTful Web Services,是一组java接口,支持Restful风格的WebService开发。JAX-RS是面向资源的,将网络上的东西当做一种资源,每次请求都是对该资源进行操作,比如对资源的增删查改,也就是对RESTful风格的webService实现,具体框架:
CXF:不仅实现了JAX-WS和实现了JAX-RS。
Jersey——Sun公司的JAX-RS参考实现。
RESTEasy——JBoss的JAX-RS项目
Restlet——也许是最早的REST框架了,它在JAX-RS之前就有了。
使用Jersey实现RESTful架构风格的webService服务器和客户端
服务器端配置如下->
第一步:在web.xml中配置ServletContainer
rest web Service
com.sun.jersey.spi.container.servlet.ServletContainer
com.sun.jersey.config.property.packages
com.zhagnxy.ws
1
rest web Service
/rest/*
第二步:编写处理请求的方法
package com.zhagnxy.ws;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("UserInfoWS")
public class UserInfoWS {
@GET
@Path("/name/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String name(@PathParam("id") long id) {
return "您的查询ID:"+id+"对应的name为:zhangxy。";
}
@GET
@Path("/age/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String age(@PathParam("id") long id) {
return "您的查询ID:"+id+"对应的age为:27。";
}
}
客户端调用代码如下:
package com.zhangxy.client.rest;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
public class UserInfoClient {
private static final String BASE_URI = "http://localhost:8080/RESTfulWS/";
private static final String PAGE_NAME = "/UserInfoWS/name/";
public static void main(String [] args) {
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource webRecource = client.resource(BASE_URI);
int id = 1000;
WebResource nameResource = webRecource.path("rest").path(PAGE_NAME+id);
String path = nameResource.getURI().toString();
System.out.println("path->"+path);
String httpStatus = nameResource.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class).toString();
System.out.println("httpStatus->"+httpStatus);
String resultStr = nameResource.accept(MediaType.TEXT_PLAIN).get(String.class).toString();
System.out.println("resultStr->"+resultStr);
}
}
使用CXF实现RESTFul架构风格的webService服务器和客户端
服务器端配置如下->
第一步:配置web.xml文件
CXF的服务器端需要借助Spring才能进行发布,所有需要配置Spring ApplicationContext。
Archetype Created Web Application
contextConfigLocation
/WEB-INF/cxf-beans.xml
org.springframework.web.context.ContextLoaderListener
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
CXFServlet
org.apache.cxf.transport.servlet.CXFServlet
1
CXFServlet
/rest/*
cxf-beans.xml
第二步:编写服务代码
和Jersey的RESTful webService代码一样,因为都是JAX-RS规范呗!
package com.zhangxy.ws;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("UserInfoWS")
public class UserInfoWS {
@GET
@Path("/name/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String name(@PathParam("id") long id) {
return "您的查询ID:"+id+"对应的name为:zhangxy。";
}
@GET
@Path("/age/{id}")
@Produces(MediaType.TEXT_PLAIN)
public String age(@PathParam("id") long id) {
return "您的查询ID:"+id+"对应的age为:27。";
}
}
客户端调用代码:
package com.zhangxy.client.cxfrestful;
import javax.ws.rs.core.MediaType;
import org.apache.cxf.jaxrs.client.WebClient;
public class UserInfoClient {
private static final String BASE_URI = "http://localhost:8080/CXFRESTfulDemo/";
private static final String PAGE_NAME = "/rest/UserInfoWS/age/100";
public static void main(String [] args) {
WebClient webClient = WebClient.create(BASE_URI);
String result = webClient.path(PAGE_NAME).accept(MediaType.TEXT_PLAIN).get(String.class);
System.out.println("result->"+result);
}
}
使用CXF使用XML+HTTP风格架构的webService服务器端和客户端
服务器端配置如下:
我们可以看到使用CXF发布XML+HTTP架构风格webService和CXF发布RESTful架构风格的webService配置步骤几乎是一样,不一样的地方是在配置处理方法时使用的注解不一样,注解是来自javax.ws.*包中的。还有就是cxf-beans.xml配置不一样。
第一步:配置配置web.xml文件
Archetype Created Web Application
contextConfigLocation
/WEB-INF/cxf-beans.xml
org.springframework.web.context.ContextLoaderListener
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
CXFServlet
org.apache.cxf.transport.servlet.CXFServlet
1
CXFServlet
/webservice/*
cxf-beans.xml
package com.zhangxy.ws;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface IUserInfoWS {
@WebMethod
String name(@WebParam(name = "id")long id);
@WebMethod
String age(@WebParam(name = "id")long id);
}
package com.zhangxy.ws;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService(endpointInterface = "com.zhangxy.ws.IUserInfoWS")
public class UserInfoWS implements IUserInfoWS {
@Override
public String name(@WebParam(name = "id") long id) {
return "您的查询ID:" + id + "对应的name为:zhangxy。";
}
@Override
public String age(@WebParam(name = "id") long id) {
return "您的查询ID:" + id + "对应的age为:27。";
}
}
客户端调用服务器端代码(实现方式一)
package com.zhangxy.client.cxf;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class JaxWsDynamicClientFactoryForClient {
public static void main(String[] args) throws Exception {
JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();
Client client = clientFactory.createClient("http://localhost:8080/CXFDemo/webservice/UserInfo?wsdl");
Object[] result = client.invoke("name", 100L);
System.out.println("result->"+result[0]);
}
}
客户端调用服务器端代码(实现方式二)
package com.zhangxy.client.cxf;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.zhangxy.ws.IUserInfoWS;
public class JaxWsProxyFactoryBeanForClient {
public static void main(String[] args) {
JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();
bean.setServiceClass(IUserInfoWS.class);
bean.setAddress("http://localhost:8080/CXFDemo/webservice/UserInfo");
IUserInfoWS userInfo = (IUserInfoWS) bean.create();
String result = userInfo.name(1000);
System.out.println("result->"+result);
}
}
客户端调用服务器端代码(实现方式三)
这种方式属于使用CXF提供的wsdl2java生产客户端代码。首先我们需要下载CXF到本地,然后配置CXF的环境变量。
打开cmd输入wsdl2java命令,如果出现wsdl2java命令帮助,说CXF配置成功。之后执行F:\eclipse-workspace\WebServiceClient\src\main\java>wsdl2java http://localhost:8
080/CXFDemo/webservice/UserInfo?wsdl命令,生产的客户端代码就会在执行命令的当前目录下。
调用代码:
package com.zhangxy.client.cxf;
import com.zhangxy.ws.IUserInfoWS;
import com.zhangxy.ws.UserInfoWSService;
public class Wsdl2javaForClient {
public static void main(String[] args) {
IUserInfoWS ws = new UserInfoWSService().getUserInfoWSPort();
String result = ws.name(100);
System.out.println("result->" + result);
}
}
这三种方式具体有什么却别我没有做深入的了解,感兴趣的同学可以自行百度,或者留言告诉我。
这篇博客主要是对两种风格架构的webService进行了初步的接受,并通过实现两种架构风格的服务器端和客户端是我们加深了解。其实只是皮毛而已。。。