`
hujin1979
  • 浏览: 78866 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

使用javax创建webservice服务

 
阅读更多

 

什么是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体系的服务,有时候我们选择这样做或许更好。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics