JAVA 快速实现webService (同步逻辑)

本文介绍如何通过Java快速构建SOAP WebService服务及客户端调用流程,包括服务端搭建、WS-DSLL文件解析及客户端接口调用实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天因为需要调用第三方的接口些fake service, 用于testcase. 该第三方使用的是soap的webservice模式。

首先是创建service。 

package myws;

import java.io.IOException;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.ws.Endpoint;

/**
 *
 * @author 帐前卒
 *
 */
@WebService(
        name="HELLO",
        targetNamespace="http://chillyc.info/api", 
        serviceName="API", 
        portName="PortName")
public class WebServiceHolder {
    @WebMethod
    @WebResult(name="return")
    public String hello(@WebParam(name="name")String name) {
        return "hello" + name;
    }
    
    public static void main(String[] args) throws IOException {
        Endpoint.publish("http://localhost:80/fake/ws", new WebServiceHolder());
        System.in.read();
    }
}

这里写System.in.read();是希望服务在那里卡死。基本上所有的server都是类似死循环的写法。所以我这里就偷懒使用IO.

这里要注意的是@WebService annotation. 其中 name是指这个portType 叫什么。 targetNameSpace这个在所有的后续调用中名字都是一致的。serviceName就是服务的名称。portName 其实就是提供服务的端口名称(这里对服务本身的调用没有什么关系)。如果没有name, 那么java会默认使用WebServiceHolder 也就类名称作为name.

运行后,在浏览器中打开 

http://localhost:80/fake/ws?wsdl
然后就可以看到wsdl文件。

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!--
 Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
-->
<!--
 Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
-->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://chillyc.info/api" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://chillyc.info/api" name="API">
<types>
<xsd:schema>
<xsd:import namespace="http://chillyc.info/api" schemaLocation="http://localhost/fake/ws?xsd=1"/>
</xsd:schema>
</types>
<message name="hello">
<part name="parameters" element="tns:hello"/>
</message>
<message name="helloResponse">
<part name="parameters" element="tns:helloResponse"/>
</message>
<message name="getReturnInfo">
<part name="parameters" element="tns:getReturnInfo"/>
</message>
<message name="getReturnInfoResponse">
<part name="parameters" element="tns:getReturnInfoResponse"/>
</message>
<portType name="HELLO">
<operation name="hello">
<input message="tns:hello"/>
<output message="tns:helloResponse"/>
</operation>
<operation name="getReturnInfo">
<input message="tns:getReturnInfo"/>
<output message="tns:getReturnInfoResponse"/>
</operation>
</portType>
<binding name="PortNameBinding" type="tns:HELLO">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="hello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="getReturnInfo">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="API">
<port name="PortName" binding="tns:PortNameBinding">
<soap:address location="http://localhost/fake/ws"/>
</port>
</service>
</definitions>

大家自己对照刚才的那些name, serviceName等,在wsdl文件中的什么地方。

然后是写一个stub作为调用的接口。

package myws;

import javax.jws.WebParam;
import javax.jws.WebService;

/**
 *
 * @author 帐前卒
 *
 */
@WebService(targetNamespace = "http://chillyc.info/api", name="HELLO")
public interface WebServiceAPI {
    String hello(@WebParam(name="name")String name);

}


这里要注意的是 那个hello函数,必须与webService发布的函数名相一致(要看wdsl文件中的名字。) 另外WebParam中的name也需要和发布函数中的参数名字一致。 这里WebService中传入了两个值。其中name就是刚才WebService中的name. 其实就是wsdl中的portType. 如果这里写错了。就会有Undefined port type:{http://chillyc.info/api}Name. 这个错误。所以要小心。

另外写个可执行的类。
package myws;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

/**
 *
 * @author 帐前卒
 *
 */
public class Client {
    public static void main(String[] args) throws MalformedURLException {
        WebServiceAPI api = Service.create(
                new URL("http://localhost:80/fake/ws?wsdl"),
                new QName("http://chillyc.info/api", "API"))
                .getPort(WebServiceAPI.class);
        System.out.println(api.hello("sss"));
    }
}

这里URL中的就是wsdl文件的地址。 QName传入的就是targetNamespace 和 serviceName. 另外getPort就填入刚才的stub. 然后直接调用stub中的接口就能得到结果。

done.

简单快速,搭建和写client 也就是10分钟搞定。当然这只是起步

这个方法适用于JDK6及以上,其他版本未知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值