Webservice
名词解释:
SOA(Service-OrientedArchitecture)
面向服务架构是一种思想,它将应用程序的不同功能单元通过中立的契约(独立于硬件平台、操作系统和编程语言)联系起来,使得各种形式的功能单元更好的集成。
WebService
也称作 XMLWeb Service,是一种可以接收从 Internet或 Intranet上的其它系统中传递过来的请求,是轻量级的独立的通讯技术.通过SOAP在 Web上提供软件服务,使用WSDL文件进行说明,通过UDDI进行注册.
XML– (Extensible Markup Language)
可扩展型标记语言.面向短期的临时数据处理,面向万维网络,是SOAP的基础.SOAP– (Simple Object Access Protocol)
简单对象存取协议,是XMLWEB SERVICE 的通信协议.当用户通过UDDI找到你的 WSDL描述文档后,可以通过SOAP调用你建立的 WEB服务中的一个或多个操作.SOAP 是 XML文档的调用方法的规范,它支持不同的底层接口,例如HTTP或 SMTP.
WSDL– (Web Services Description Language)
WSDL文件是一个 XML文档,用于说明一组SOAP消息以及如何交换这些消息,大多数的情况由软件自动生成和使用.
UDDI– (Universal Description,Discovery,and Integration)
是一个主要针对 Web服务供应商和使用者的新项目.在用户能够调用Web服务之前,必须确定这个服务内包含哪些商业方法,找到被调用的接口定义,还要在服务端来编制软件,UDDI 是一种根据描述文档来引导系统查找相应服务的机制.UDDI 利用 SOAP消息机制(标准的XML/ HTTP)来发布,编辑,浏览以及查找注册信息.它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据.
JWS (javawebservice)
JAX-WS (JavaTMAPIforXML-Based Web Services)
JAX-RS (JavaTMAPIforRESTful Web Services)
JAXB (Javaxml binding)
是jax-rsjax-ws底层使用的对象与xml之间转换的工具
JAX-RPC(JavaAPI For XML-Remote Procedure Call)
目前已经被JAX-WS规范取代
JAVA中的Web服务规范:
JAVA中共有三种WebService规范,分别是JAXM&SAAJ、JAX-WS(JAX-RPC)、JAX-RS。
下面来分别简要的介绍一下这三个规范。
JAXM(JAVAAPI For XML Message)主要定义了包含了发送和接收消息所需的API
JAXM&SAAJ与JAX-WS都是基于SOAP的Web服务,相比之下JAXM&SAAJ暴漏了SOAP更多的底层细节,编码比较麻烦,而JAX-WS更加抽象,隐藏了更多的细节,更加面向对象,实现起来你基本上不需要关心SOAP的任何细节。
JAX-WS是JAX-RPC的演进版本,但JAX-WS并不完全向后兼容JAX-RPC,二者最大的区别就是RPC/encoded样式的WSDL,JAX-WS已经不提供这种支持。
JAX-RS是JAVA针对REST(RepresentationState Transfer)风格制定的一套Web服务规范。
例子:
原地址http://www.open-open.com/lib/view/open1328150536796.html
1、准备
这是一个最基本的基于CXF的Java项目
如果仅发布JAX-WS应用则需要以下jar文件:
cxf-2.4.2.jar 这是CXF的核心包
xmlschema-core-2.0.jar 这是解析XMLSchema的apache包
neethi-3.0.1.jar apache的WebService策略包
wsdl4j-1.6.2.jar wsdl文件生成包
servlet-api.jar 此包就不用多说了吧。。
jetty-util-7.4.5.v20110725.jar //因为CXF使用内嵌的jetty服务器,以下都是jetty服务器包。
jetty-server-7.4.5.v20110725.jar
jetty-http-7.4.5.v20110725.jar
jetty-io-7.4.5.v20110725.jar
jetty-continuation-7.4.5.v20110725.jar
2、
如果需要使用JAX-RS发布RESTful的服务则再添加以下jar文件:
jsr311-api-1.1.1.jar /这是SUN公司发布的WebService的新标准,此JSR311包中包含了在类上应该添加什么注解如@Post
如果需要返回JSON类型的串则再需要加入
jettison-1.3.jar //
因为cxf是用此类解析JSON串的。
(对于一个jax-rs应用,第一个方法必须返回一个JavaBean,
不能没有返回值,且类上必须使用@XmlRootElement注解)
(待续)
3、
CXF发布服务的类:
lJaxWsServerFactoryBean
•JaxWsServerFactoryBean 用于发布一个服务,可以通过默认构造实例此类。
•它的方法如下:
•setServiceBean(Object) – 设置一个服务对象 -*
•setAddress(Stringurl) – 绑定一个地址和端口 -*
•create() - 在JavaSE环境下,使用jetty发布WebService.- *
•以下是可选方法 :
•setServiceClass(Classcls) – 设置服务对象实现的接口类。
lJaxRsServerFactoryBean
•此类用于发布 RESTful风格的webService.
•RESTful 风格是以普通get,post请求为标准的,并可以请求和响应json数据。
4、使用CXF发布一个服务
packagecn.leaf.one;
importjavax.jws.WebService;
importorg.apache.cxf.jaxws.JaxWsServerFactoryBean;
/**
* 使用CXF发布一个服务
* 必须要添加WebService注解。否则不会对外暴露任何一个方法
*@author 王健
*/
@WebService
publicclass OneService {
publicString sayHi(){ ///此方法将会对外公布
return"Good";
}
publicstatic void main(String[] args) throws Exception {
JaxWsServerFactoryBeanbean //使用 jaxWs对其进行发布
=new JaxWsServerFactoryBean();
bean.setServiceBean(newOneService());
bean.setServiceClass(OneService.class);
bean.setAddress("http://localhost:4444/one");
bean.create();//内部使用jetty服务器做为支持
System.err.println("服务启动成功。。 ");
//Thread.sleep(1000*60*60);
//System.exit(0);
}
}
5、获取上面的wsdl文件: http://localhost:4444/one?wsdl
6、使用wsimport或是wsdl2java生成客户端调用代码,略。
7、发布一个RESTful的webService
packagecn.itcast.ws3;
importjava.util.ArrayList;
importjava.util.List;
importjavax.ws.rs.FormParam;
importjavax.ws.rs.GET;
importjavax.ws.rs.POST;
importjavax.ws.rs.Path;
importjavax.ws.rs.PathParam;
importjavax.ws.rs.Produces;
importjavax.ws.rs.core.MediaType;
importorg.apache.cxf.interceptor.LoggingInInterceptor;
importorg.apache.cxf.interceptor.LoggingOutInterceptor;
importorg.apache.cxf.jaxrs.JAXRSServerFactoryBean;
importcn.itcast.domain.User;
/**
* 一个基于JAX-RS的服务
*JAX-RS是无状态的服务
* 注意,必须要在JavaBean上添加@XMLRootElemet注解
* 此项目启动成功以后,可以通过以下方式访问:
* http://localhost:9004/users?_wadl&_type=xml
* 注意是_wadl&_type=xml
* 将返回一个如何调用RESTfulws的wsdl文件说明书
*@author 王健
*@version 1.0 2011-11-18
*/
@Path(value="/users/") //声明uri路径
@Produces(value={MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})//声明支持的类型
publicclass UserServiceRS {
privateList<User> users = new ArrayList<User>();
publicUserServiceRS(){
Useru = new User();
u.setAge(90);
u.setName(" 大家好");
users.add(u);
}
/**
* 以下代码,请在地址栏这样访问:
* http://localhost:9004/users/all/
* 即会以XML形式显示所有用户信息
*@return
*/
@GET
@Path(value="/all/")
publicList<User> getUsers(){
System.err.println(" 调用了users方法");
returnusers;
}
/**
* 以下在地址栏输入:
*http://localhost:9004/users/save/Tom/34
* 其中:Tom为要保存的用户名,34为年龄
* 即会保存成功
*/
@GET
@Path(value="/save/{name}/{age}/")
publicUser save(@PathParam("name")Stringname,@PathParam("age")String age){
Useru = new User();
u.setAge(Integer.parseInt(age));
u.setName(name);
System.err.println(" 保存成功"+u);
users.add(u);
returnu;
}
/**
* 提供第二种保存方式
* 使用@FormParam方式设置接收表单的参数
* 通过HttpClient调用,并设置请求参数
*/
@POST
@Path(value="/add/")
publicUser add(@FormParam("name")Stringname,@FormParam("age")String age){
Useru = new User();
u.setAge(Integer.parseInt(age));
u.setName(name);
System.err.println(" 使用POST保存成功"+u);
users.add(u);
returnu;
}
publicstatic void main(String[] args) {
JAXRSServerFactoryBeanbean = // 声明JAXRS服务对象
newJAXRSServerFactoryBean();
bean.setServiceBean(newUserServiceRS());// 加载服务类
bean.setAddress("http://localhost:9004/");// 声明地址,注意只声明地址和端口即可
bean.getInInterceptors().add(newLoggingInInterceptor());
bean.getOutInterceptors().add(newLoggingOutInterceptor());
bean.create();// 启动
System.err.println("JAX-RS 启动成功....");
}
}
8、使用HttpClient调用RESTful的web服务:
packagecn.itcast.ws3;
importorg.apache.commons.httpclient.HttpClient;
importorg.apache.commons.httpclient.methods.GetMethod;
importorg.apache.commons.httpclient.methods.PostMethod;
/**
* 使用URLConnection调用RESTful的服务
* 此外建议使用httpClient读取,将会更快
* 使用urlConnection可能没有返回结果
*@author 王健
*@version 1.0 2011-11-18
*/
publicclass UserRsClient {
UserRsClient()throws Exception{
save2();
all();
}
/**
* 查询所有信息
*@throws Exception
*/
privatevoid all() throws Exception{
GetMethodget = new GetMethod("http://localhost:9004/users/all");
get.setRequestHeader("accept","application/json");
HttpClienthc = new HttpClient();
hc.getParams().setContentCharset("UTF-8"); // 设置编码
intcode = hc.executeMethod(get);
System.err.println(" 返回的状态码:"+code);
if(code==200){
Stringstr = get.getResponseBodyAsString();
System.err.println(" 返回信息:\n"+str);
}
get.releaseConnection();
}
/**
* 保存一条信息,仍然使用GET方式
*/
privatevoid save() throws Exception{
Stringname = "Jack";// 因为是get类型,所以不能包含中文
Stringage = "35";
Stringurl = "http://localhost:9004/users/save/"+name+"/"+age;
GetMethodget = new GetMethod(url);
get.setRequestHeader("accept","application/json");
HttpClienthc = new HttpClient();
hc.getParams().setContentCharset("UTF-8"); // 设置编码
//.setRequestHeader("Content","text/html;charset=UTF-8");
intcode = hc.executeMethod(get);
System.err.println(" 返回的状态码是:"+code);
if(code==200){
Stringstr = get.getResponseBodyAsString();
System.err.println(" 返回的信息是:\n"+str);
}
get.releaseConnection();
}
/**
* 以下使用POST方式
*/
privatevoid save2() throws Exception{
Stringname = " 王健";//因为是get类型,所以不能包含中文
Stringage = "35";
Stringurl = "http://localhost:9004/users/add/";
PostMethodpm = new PostMethod(url);
pm.setRequestHeader("accept","application/json");
pm.setRequestHeader("Encoding","UTF-8");
pm.setParameter("name",name);
pm.setParameter("age",age);
HttpClienthc = new HttpClient();
hc.getParams().setContentCharset("UTF-8");// 设置编码,否则会返回中文乱码//TODO:切记
intcode = hc.executeMethod(pm);
System.err.println("Post 方式的返回值是:"+code);
if(code==200){
Stringss = pm.getResponseBodyAsString();
System.err.println(">>:"+ss);
}
pm.releaseConnection();
}
publicstatic void main(String[] args) throws Exception {
newUserRsClient();
}
}
cxf动态调用webservice
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
public class WSClient {
public static void main(String[] args)throws Exception {
String wsdlUrl = "http://172.16.11.11:8080/webws/CalculatorPort?wsdl";
//动态调用的客户端工厂类
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
final Client client = factory.createClient(wsdlUrl);
//设置超时单位为毫秒
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(3000); //连接超时
httpClientPolicy.setAllowChunking(false); //取消块编码
httpClientPolicy.setReceiveTimeout(3000); //响应超时
http.setClient(httpClientPolicy);
//用线程池试了下client对象线程安全性,发现是安全的
ThreadPoolExecutor pool = new ThreadPoolExecutor(5,50,1000,
TimeUnit.MICROSECONDS,new ArrayBlockingQueue<Runnable>(50));
for (int i=0;i<100;i++){
pool.execute(new Runnable() {
@Override
public void run() {
try {
String threadName = Thread.currentThread().getName();
int a = new Random().nextInt(10);
int b = new Random().nextInt(10);
Object[] res = client.invoke("adD", a,b);
System.out.println(threadName+":"+a+"+"+b+"="+res[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
原帖地址:http://ruijf.iteye.com/blog/1186961