XML+HTTP风格架构和RESTful风格架构的webService

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fly_zxy/article/details/78885685

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
<servlet>
		<servlet-name>rest web Service</servlet-name>
		<servlet-class>
			com.sun.jersey.spi.container.servlet.ServletContainer
		</servlet-class>
		<init-param>
			<param-name>
				com.sun.jersey.config.property.packages
			</param-name>
			<param-value>com.zhagnxy.ws</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>rest web Service</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>

第二步:编写处理请求的方法
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。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<display-name>Archetype Created Web Application</display-name>

	<!-- 配置 Spring 配置文件的名称和位置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/cxf-beans.xml</param-value>
	</context-param>
	<!-- 启动 IOC 容器的 ServletContextListener -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 配置字符集 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- 配置CXFServlet拦截WebService请求 -->
	<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>

</web-app>

cxf-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd 
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

	<jaxrs:server id="userInfoWS" address="/">
		<jaxrs:serviceBeans>
			<bean class="com.zhangxy.ws.UserInfoWS" />
		</jaxrs:serviceBeans>
	</jaxrs:server>

</beans>

第二步:编写服务代码
和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文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<display-name>Archetype Created Web Application</display-name>

	<!-- 配置 Spring 配置文件的名称和位置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/cxf-beans.xml</param-value>
	</context-param>
	<!-- 启动 IOC 容器的 ServletContextListener -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 配置字符集 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- 配置CXFServlet拦截WebService请求 -->
	<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/webservice/*</url-pattern>
	</servlet-mapping>

</web-app>

cxf-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">

	<!--=============== 实现类的bean,需要spring注入 ============================ -->
	<!-- <bean id="greetingImpl" class="com.moon.cxfWebservice.server.GreetingImpl"/> 
		<jaxws:endpoint id="greeting" implementor="#greetingImpl" address="/Greeting" 
		/> -->

	<jaxws:endpoint id="userInfoWS" implementor="com.zhangxy.ws.UserInfoWS"
		address="/UserInfo">
	</jaxws:endpoint>

</beans>

第二步:编写服务器代码
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进行了初步的接受,并通过实现两种架构风格的服务器端和客户端是我们加深了解。其实只是皮毛而已。。。




猜你喜欢

转载自blog.csdn.net/fly_zxy/article/details/78885685