什么是WebServices?
它是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行;它是一种新的web应用程序分支,是自包含、自描述、模块化的应用,可以发布、定位、通过web调用。Web Service是一个应用组件,它逻辑性的为其他应用程序提供数据与服务.各应用程序通过网络协议和规定的一些标准数据格式(Http,XML,Soap)来访问Web Service,通过Web Service内部执行得到所需结果.Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。
关键的技术和规则
在构建和使用Web Service时,主要用到以下几个关键的技术和规则:
1.XML:描述数据的标准方法.
2.SOAP:表示信息交换的协议.
3.WSDL:Web服务描述语言.
4.UDDI:通用描述、发现与集成,它是一种独立于平台的,基于XML语言的用于在互联网上描述商务的协议。
XML
可扩展的标记语言(XML)是Web service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。
SOAP
SOAP是web service的标准通信协议,SOAP为simple object access protocoll的缩写,简单对象访问协议. 它是一种标准化的传输消息的XML消息格式。
WSDL
WSDL的全称是web service Description Language,是一种基于XML格式的关于web服务的描述语言。其主要目的在于web service的提供者将自己的web服务的所有相关内容,如所提供的服务的传输方式,服务方法接口,接口参数,服务路径等,生成相应的完全文档,发布给使用者。使用者可以通过这个WSDL文档,创建相应的SOAP请求消息,通过HTTP传递给webservice提供者;web服务在完成服务请求后,将SOAP返回消息传回请求者,服务请求者再根据WSDL文档将SOAP返回消息解析成自己能够理解的内容。
UDDI
将web service进行UDDI注册发布,UDDI是一种创建注册表服务的规范,以便大家将自己的web service进行注册发布供使用者查找.然而当服务提供者想将自己的web service向全世界公布,以便外部找到其服务时,那么服务提供者可以将自己的web service注册到相应的UDDI商用注册网站,目前全球有IBM等4家UDDI商用注册网站。因为WSDL文件中已经给定了web service的地址URI,外部可以直接通过WSDL提供的URI进行相应的web service调用。所以UDDI并不是一个必需的web service组件,服务方完全可以不进行UDDI的注册。
签于webservice开发C/S或B/S结构中的重要性,一直在研究其原理。本章主要讲述使用JDK自带的javax扩展包创建webservice服务的过程。我们创建通用性高的web服务接口时一般采取java基础类型来作为参数传递和返回,比如string,byte[],int等。string多采用XML格式来进行规范化交互,byte[]常用来进行二进制的处理,这样使用web service可以做很多设计了。
我们提供一个范式的服务器端代码:
import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.WebServiceContext;
import com.sun.net.httpserver.HttpExchange;
import com.ue.dto.CrackBean;
import com.ue.server.CrackControl;
import com.ue.util.ConvertUtils;
@WebService (name = "client" , targetNamespace = "http://ws.ue.com", serviceName = "client" )
@SOAPBinding (style = SOAPBinding .Style. RPC)
public class CrackClientImp implements CrackClient
{
@Resource
private WebServiceContext wsContext ;
private String getIp()
{
HttpExchange exchange = (HttpExchange) wsContext .getMessageContext().get("com.sun.xml.internal.ws.http.exchange" );
String remortAddress = exchange.getRemoteAddress().getAddress().getHostAddress();
return remortAddress;
}
// 获得破解开
@WebMethod (operationName = "getCrack" , action = "getCrack", exclude = false )
@WebResult (name = "returnWord" )
public byte [] getCrack ()
{
byte [] defaultvalue = "" .getBytes();
byte [] code = null;
CrackControl c = CrackControl. getInstance();
CrackBean bean = c.take();
if (bean != null)
{
byte [] name = bean.getTypeName().getBytes();
byte [] pack = ConvertUtils.intToBytes4(name. length );
byte [] content = bean.getContent();
code = new byte [content. length + pack. length + name.length ];
System. arraycopy(pack, 0, code, 0, pack. length);
System. arraycopy(name, 0, code, pack. length, name.length );
System. arraycopy(content, 0, code, pack. length + name.length , content.length );
}
if (code== null){
//throw new RuntimeException("Exception in getCrack()");
code = defaultvalue;
}
return code;
}
// 获得破解开
@WebMethod (operationName = "crack" , action = "crack", exclude = false )
public void crack (@WebParam (partName = "id")
String id, @WebParam (partName = "crackValue" )
String crackValue)
{
CrackControl c = CrackControl. getInstance();
c.setCrackCode(id, crackValue);
}
// 获得破解开
@WebMethod (operationName = "unCrack" , action = "unCrack", exclude = false )
public void unCrack (@WebParam (partName = "id")
String id)
{
CrackControl c = CrackControl. getInstance();
c.unCrack(id);
}
@WebMethod (operationName = "getPackLength" , action = "getPackLength" , exclude = false)
@WebResult (name = "returnWord" )
public int getPackLength (@WebParam (partName = "p")
byte [] p)
{
int value = 0;
if (p.length >= 4)
{
byte [] bytes = new byte[4];
System. arraycopy(p, 0, bytes, 0, 4);
value = ConvertUtils. byteToInt(bytes);
}
return value;
}
}
public class Server
{
public static void main(String[] args) throws IOException {
CrackServerImp server = new CrackServerImp();
/*
* 发布Web Service
*/
String ip = InetAddress. getLocalHost().getHostAddress();
Endpoint clientEndpoint = Endpoint. publish( "http://" + ip + ":7000/client" ,server );
Binding clientBinding = clientEndpoint.getBinding();
List<Handler> clientHandlerChain = new LinkedList<Handler>();
clientHandlerChain.add( new ClientTraceHandler());
clientBinding. setHandlerChain(clientHandlerChain);
}
}
Annotation 1:@WebService(name="client", targetNamespace="http://ws.ue.com", serviceName="client")
@WebService标签主要将类暴露为WebService,其中targetNamespace属性定义了自己的命名空间,serviceName则定义了< definitions >标签和<service>标签的name属性。
Annotation 2:@SOAPBinding(style=SOAPBinding.Style.RPC)
@SOAPBinding标签定义了WSDL文档中SOAP的消息协议,其中style属性对应SOAP的文档类型,可选的有RPC和DOCUMENT
Annotation 3:@WebMethod(operationName="getCrack",action="getCrack",exclude=false)
@WebMethod定义Web Service运作的方法,
属性action 对应操作的活动 ,如<soap:operation soapAction="getCrack" />
属性operationName匹配的wsdl:operation 的名称,如<operation name="getCrack" parameterOrder="userName">
属性exclude 用于阻止将某一继承方法公开为web服务,默认为false
Annotation 4:@WebResult(name="returnWord")
@ WebResult定义方法返回值得名称,如<part name="returnWord" type="xsd:string" />
在产生的WSDL文档中,message元素反映了这个变化:
<message name="getTimeAsString"/>
<message name="getTimeAsStringResponse">
<part name="time_response" type="xsd:string"/>
</message>
<message name="getTimeAsElased"/>
<message name="getTimeAsElasedResponse">
<part name="time_response" type="xsd:long"/>
</message>
没有添加@WebResult注解之前,WSDL文档中,message元素是这样的:
<message name="getTimeAsString"/>
<message name="getTimeAsStringResponse">
<part name="return" type="xsd:string"/>
</message>
<message name="getTimeAsElased"/>
<message name="getTimeAsElasedResponse">
<part name="return" type="xsd:long"/>
</message>
两个message元素对比,我们可以看出,return标签被换成了time_response,也就是@WebResult注解定义的。在从web服务返回的SOAP消息中也同样反映出了这点变化,以调用getTimeAsString服务方法为例:
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getTimeAsStringResponse xmlns:ns2="http://ts.ch01/">
<time_response>Mon Mar 17 10:41:13 CST 2014</time_response>
</ns2:getTimeAsStringResponse>
</S:Body>
</S:Envelope>
没有添加@WebResult注解时,SOAP消息返回是这样的:
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getTimeAsStringResponse xmlns:ns2="http://ts.ch01/">
<return>Mon Mar 17 10:46:30 CST 2014</return>
</ns2:getTimeAsStringResponse>
</S:Body>
</S:Envelope>
从SOAP消息对比中,我们也可以看到,return标签也相应地被替换成了time_response标签。假设我们只对getTimeAsString增加@WebResult注解,那么返回的SOAP消息中针对该服务操作使用time_response标签,而针对getTimeAsElapsed服务操作所返回的SOAP消息中仍然使用默认的return标签。
Annotation 5:@WebParam(partName="person", mode=Mode.IN
@WebParam定义方法的参数名称,如<part name="person" type="tns:person" />,其中mode属性表示参数的流向,可选值有IN / OUT / INOUT
我们提供一个范式的客户器端代码:
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
@WebServiceClient (name = "client" , targetNamespace = "http://ws.ue.com", wsdlLocation = "http://10.0.108.194:7000/client?wsdl" )
public class ClientService extends Service
{
private final static URL CLIENT_WSDL_LOCATION;
static
{
URL url = null ;
try
{
url = new URL("http://10.0.108.194:7000/client?wsdl" );
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
CLIENT_WSDL_LOCATION = url;
}
public ClientService(URL wsdlLocation, QName serviceName)
{
super (wsdlLocation, serviceName);
}
public ClientService()
{
super ( CLIENT_WSDL_LOCATION, new QName( "http://ws.ue.com" , "client" ));
}
/**
*
* @return returns Client
*/
@WebEndpoint (name = "clientPort" )
public Client getClientPort()
{
return (Client) super.getPort( new QName( "http://ws.ue.com" , "clientPort" ), Client. class);
}
}
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService (name = "client" , targetNamespace = "http://ws.ue.com", serviceName = "client" )
@SOAPBinding (style = SOAPBinding .Style. RPC)
public interface Client
{
// 获得破解开
@WebMethod (operationName = "getCrack", action = "getCrack" , exclude = false )
@WebResult (name = "returnWord" )
public byte [] getCrack();
// 获得破解开
@WebMethod (operationName = "crack", action = "crack" , exclude = false )
public void crack( @WebParam(partName = "id" )
String id, @WebParam (partName = "crackValue" )
String crackValue);
@WebMethod (operationName = "getPackLength", action = "getPackLength" , exclude = false)
@WebResult (name = "returnWord" )
public int getPackLength( @WebParam(partName = "p" )
byte [] p);
// 不填了
@WebMethod (operationName = "unCrack", action = "unCrack" , exclude = false )
public void unCrack( @WebParam(partName = "id" )
String id);
}
import com.ue.dto.CrackBean;
import com.ue.ws.client.Client;
import com.ue.ws.client.ClientService;
import com.ue.ws.client.HandlerResolverImp;
public class TestClient
{
public static void main(String[] args)
{
ClientService cs = new ClientService();
HandlerResolver hr = new HandlerResolverImp("ue" , "ue123456" );
cs.setHandlerResolver(hr);
Client c = cs.getClientPort();
byte [] bytes = c.getCrack();
byte [] p = new byte[4];
System. arraycopy(bytes, 0, p, 0, 4);
int cl = c.getPackLength(p);
byte [] typeName = new byte[cl];
System. arraycopy(bytes, 4, typeName, 0, cl);
byte [] content = new byte[bytes. length -cl-4];
System. arraycopy(bytes, cl+4, content, 0, content. length );
CrackBean cb = new CrackBean( new String(typeName),content);
System. out .println(cb.getTypeName());
}
}
当然我们完全可以使用Xfire搭建基于B/S架构的web service,这个在之前的文章中已经有讲述。javax的好处是完全脱离servlet容器的支持,我们就可以搭建非web体系的服务,有时候我们选择这样做或许更好。
相关推荐
在网上找了很久的资料,接口已经跟客户对接,特编写了代码文档和附带jar包,并含其他网站的参考地址,注意jdk环境要1.6或以上版本
jax webservice 服务器和客户端示例程序
javax-ws java自带webservice实现方式 简单代码实现
开发基于JWS的webservice并通过jun-jaxws发布所需的jar包
javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar javax.jar ...
javax.jms.BytesMessage.class javax.jms.Connection.class javax.jms.ConnectionConsumer.class javax.jms.ConnectionFactory.class javax.jms.ConnectionMetaData.class javax.jms.DeliveryMode.class javax.jms....
Classes contained in javax.jms.jar: javax.transaction.xa.XAResource.class javax.jms.BytesMessage.class javax.jms.Message.class javax.jms.JMSException.class javax.jms.Destination.class javax.jms....
my-webservice 是一个项目网络服务。 使用 javax.jws 包。 网址:
webService的实现方式之一JWS,有需要的同学可以下载代码抽空研究;
Files contained in javax.persistence.jar: META-INF/MANIFEST.MF javax.persistence.Access.class javax.persistence.AccessType.class javax.persistence.AssociationOverride.class javax.persistence....
javax.usb.jar
jws与spring发布WebService
使用javax Nullable注解必须使用的jar包
通过java扩展包javax.mail-1.4.4.jar实现邮件发送功能。 import javax.mail.Address; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart...
一、利用jdk web服务api实现,这里使用基于 SOAP message 的 Web 服务 1.首先建立一个Web services EndPoint: Java代码 package Hello; import javax.jws.WebService; import javax.jws.WebMethod; import ...
java axis客户端调用webservice,可应用于ofbiz框架。 解决网络上共享代码两次调用后会出现timeout的BUG
赠送jar包:javax.mail-1.5.6.jar; 赠送原API文档:javax.mail-1.5.6-javadoc.jar; 赠送源代码:javax.mail-1.5.6-sources.jar; 赠送Maven依赖信息文件:javax.mail-1.5.6.pom; 包含翻译后的API文档:javax.mail...
Files contained in javax.servlet.jar: META-INF/MANIFEST.MF javax/servlet/http/LocalStrings.properties javax.servlet.http.HttpSessionBindingListener.class javax.servlet....
赠送jar包:javax.mail-1.6.2.jar; 赠送原API文档:javax.mail-1.6.2-javadoc.jar; 赠送源代码:javax.mail-1.6.2-sources.jar; 赠送Maven依赖信息文件:javax.mail-1.6.2.pom; 包含翻译后的API文档:javax.mail...
rest 开发webservice必备的jar包,rest开发webservice是一个http协议轻量级组件,简单,上手快,调用方便