扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
1.配置一个Web服务的最简方法
为了能让web服务先跑起来,先给出一个Web服务的原型,以便于后面的讨论。
我们从一个最简单的例子开始,只给出必须的东西。
所需软件:
1.Tomcat4.1.2
2.一个Java编译器,jdk或JBuilder等等,这是为了编译我们的Java源程序,于web服务无关。
所需文件:
1.sayHello.java
2.web.xml
3.server-config.xml
4.Java Packages: axis.jar,jaxrpc.jar,tt-bytecode.jar,wsdl4j.jar,xercesImpl.jar,xml-apis.jar
至于Tomcat怎么安装我就不说了,网上关于Tomcat安装的文章有很多。
这六个package,从ibm和apache的网站上都可以下得到。
只需要这些,我们就可以部署自己的Web服务了。。
下面是目录结构:
webapps/test/WEB-INF/web.xml
webapps/test/WEB-INF/server-config.wsdd
webapps/test/WEB-INF/classes/sayHello.class
webapps/test/WEB-INF/lib/xxx.jar ---所需得六个packages
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<servlet>
<servlet-name>Axis</servlet-name>
<!--实际servlet程序,这里是AxisServlet-->
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<!-- ### 定义servlet和url的对应关系-->
<servlet-mapping>
<servlet-name>Axis</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
server-config.wsdd
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns="http://xml.apache.org/axis/wsdd/">
<handler type="javarg.apache.axis.handlers.http.URLMapper" name="URLMapper"/>
<service name="sayHelloService" provider="java:RPC">
<parameter name="className" value="sayHello"/>
<parameter name="allowedMethods" value="sayHelloTo"/>
</service>
<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
</requestFlow>
</transport>
</deployment>
sayHello.java
public class sayHello
{
public String sayHelloTo(String aname)
{
return "How are you, " + aname;
}
}
假设ip地址192.168.0.1,端口号是80,我们输入下面的url得到服务列表(当然这里只有一个):
http://192.168.0.1/test/services
如果你的端口号是8080,就应该输入http://192.168.0.1:8080/test/services,后面同理。
浏览器显示:
|And now... Some Services |
| sayHelloService (wsdl) |
| .sayHelloTo |
sayHelloService是我们的服务名,右侧的 (wsdl)是一个链接指向sayHelloService的WSDL文档,
这个文档是由Axis自动生成的。
sayHelloTo当然就是我们的方法了。。。
点击(wsdl)链接或输入下面的url,得到WSDL:
http://192.168.0.1/test/services/sayHelloService?wsdl
浏览器显示sayHelloService的WSDL文档:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService-impl" xmlns:intf="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlnssd="http://www.w3.org/2001/XMLSchema">
<wsdl:message name="sayHelloToResponse">
<wsdl:part name="return" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="sayHelloToRequest">
<wsdl:part name="aname" type="xsd:string"/>
</wsdl:message>
<wsdl:portType name="sayHello">
<wsdlperation name="sayHelloTo" parameterOrder="aname">
<wsdl:input message="intf:sayHelloToRequest" name="sayHelloToRequest"/>
<wsdlutput message="intf:sayHelloToResponse" name="sayHelloToResponse"/>
</wsdlperation>
</wsdl:portType>
<wsdl:binding name="sayHelloServiceSoapBinding" type="intf:sayHello">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdlperation name="sayHelloTo">
<wsdlsoapperation soapAction=""/>
<wsdl:input name="sayHelloToRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" use="encoded"/>
</wsdl:input>
<wsdlutput name="sayHelloToResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" use="encoded"/>
</wsdlutput>
</wsdlperation>
</wsdl:binding>
<wsdl:service name="sayHelloService">
<wsdl:port binding="intf:sayHelloServiceSoapBinding" name="sayHelloService">
<wsdlsoap:address location="http://192.168.0.1/test/services/sayHelloService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我们甚至不用客户端,就可以查看服务是否部署成功以及获得返回结果
用Get方法获得soap流,我们要用下面的url:
(真正调用Web服务,用的是Post方法,这个后面会讲)
http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody
浏览器显示的是乱码,我们点右键查看源文件,结果如下:
<p>Got response message</p>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlnssd="http://www.w3.org/2001/XMLSchema" xmlnssi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<sayHelloToResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<sayHelloToReturn xsi:type="xsd:string">How are you, everybody</sayHelloToReturn>
</sayHelloToResponse>
</soapenv:Body>
</soapenv:Envelope>
这就是我们想要的结果吗?这只是服务器端送回来的SOAP消息,不过我们想要的结果在里面。。。
为了真正调用我们的Web服务,下面给出一个Client:
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class test
{
public static void main(String [] args)
{
try {
String endpoint = "http://192.168.0.1/test/services/sayHelloService";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) ;
call.setOperationName(new QName("http://sayHelloService", "sayHelloTo"));
String ret = (String) call.invoke( new Object[] { args[0] } ;
System.out.println(ret);
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意要配置好正确的classpath,确保编译器能找的到axis.jar和jaxrpc.jar,否则编译不会通过。
用下面的命令行运行这个class:
java test everybody
我们会得到:How are you, everybody
这才是我们真正想要的。。。
2.追根究底,我们的Web服务是怎样跑起来的
前面给出的两个配置文件web.xml和server-config.wsdd,或许不是能一下子就看懂的。
先让我们回顾一下servlet的映射模式。
我们知道,servlet是从javax.servlet.http.HttpServlet继承的,在服务器端被载入JVM执行,然后向客户端输出html流。
servlet的web.xml文件(位于 webapps/foo/WEB-INF目录):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
</web-app>
invoker servlet 其实是:org.apache.catalina.servlets.InvokerServlet
按类名提供小服务程序。例如,如果您调用 foo/servlet/HelloServlet,
invoker servlet将装入该HelloServlet(如果它在其类路径中的话)并执行。
初看上面的web.xml,好像只给出了一个servlet映射,而没有定义invoker servlet。
其实,invoker servlet 是在tomcat的conf目录中的web.xml中定义的::
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
所以,如果抛开Tomcat_HOME/conf/web.xml,我们这样定义一个web.xml,似乎更能清楚的说明问题:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet-name>MyInvoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyInvoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
</web-app>
即所有/servlet/* 模式的url,都会交给org.apache.catalina.servlets.InvokerServlet来处理。
或者说,所有/servlet/* 模式的url,其实都是调用InvokerServlet这个类,而InvokerServlet本身也是
一个servlet,它也是从 HttpServlet 继承而来的。
这样,我们自己的servlet就能够通过特定的url执行,即 /servlet/OurServlet。
当然,如果你高兴,可以定义任何的 url pattern,而不一定是 /servlet/*,这一点,正如我们后面
看到的Axis处理Soap消息的方法。
再进一步,如果不想让 InvokerServlet 在中间“捣鬼”,我们当然可以直接定义自己的servlet:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet-name>MyInvoker2</servlet-name>
<servlet-class>
com.foo.MyServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyInvoker2</servlet-name>
<url-pattern>/AnyName/*</url-pattern>
</servlet-mapping>
</web-app>
JSP也是一样的道理,有了上面的分析,
看看Tomcat_HOME/conf/web.xml中的如下语句就可以JSP的处理方法了,这里就不再废话了:
....
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
....
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者