电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

使用WAS CE开发基于JAX-WS的RESTful服务


发布日期:2020/4/23
 

什么是REST

REST是REpresentational State Transfer的缩写代表分布式超媒体系统(如World Wide Web)上的一种软件架构体系并不仅仅是创建Web Service的一种方法它最早由Roy Fielding于年在其博士论文Architectural Styles and the Design of Networkbased Software Architectures中提出并定义了一些基本原则简单的说放到World Wide Web上就是所有的应用程序对象和功能都可以抽象为一种资源(Resource)并通过URI来定位并使用因此我们可以把符合REST原则的系统称为RESTful也就是说REST是一种架构风格而不是一个标准你永远不会看到WC发布一个叫REST的Specification

RESTful Web Service与基于SOAP和WSDL的Web Service有着很多的不同它有着以下特点

·将Web Service作为一种资源并通过URI来定位

·使用HTTP中的POSTGETPUT和DELETE方法来代表对资源的CREATEREADUPDATEDELETE(CRUD)操作

·使用无状态通信

·传输XML或者SON

在JAXWS中提供了对开发和部署一个RESTful的Web Service的基本支持即通过实现Provider接口使得Web Serivce可以对传输的XML消息进行完全的控制因此我们可以在WAS CE中使用JAXWS开发一个RESTful的Web Service

对RESTful Web Service提供完整支持的JAXRS Specification将会加入Java EE 的大家庭中当前的WAS CE Vx是遵循Java EE 的企业级应用服务器因此若想使用JAXRS开发RESTful Web Service请关注WAS CE的后续版本

开发环境设置

本文基于WAS CE的最新版本V开发一个RESTful的Web Service在开始编写代码之前请确认如下的开发环境

·Sun JDK V

·Eclipse IDE for Java EE Developers Ganymede

·WASCE Eclipse Plugin (WEP) V

此外WAS CE使用Axis作为JAXWS引擎但是由于其存在一个已知的关于HTTP ContentType Header的问题(在Axis中才解决)所以我们需要将JAXWS引擎切换成Apache CXF (WAS CE使用版本为V)不用担心WAS CE的模块化架构使这个过程十分简单过程如下

启动WAS CE

打开Web //localhost:/console

进入Application > Plugins页面点击Add Repository

由于WAS CE V是基于Geronimo V开发所以我们也可以使用Geronimo的Server plugins在New Repository中输入

/ 然后点击Add Repository

选择刚刚添加的Repository然后点击Show Plugins in selected repository

勾选上以下plugins并且点击install按钮

在以上CXF相关的Plugin安装完成之后 我们需要更新WAS CE的配置文件以使得WAS CE在启动时加载CXF以代替Axis(注意在更改配置文件前先要停止WAS CE服务器)

停止WAS CE后打开<WASCE_HOME>/var/config/configxml

去掉以下四个module的condition属性

<module name=orgnfigs/axisdeployer//car condition=/>

<module name=orgnfigs/axisejbdeployer//car condition=/>

<module name=orgnfigs/cxfdeployer//car condition=/>

<module name=orgnfigs/cxfejbdeployer//car condition=/>

增加load属性axis相关的为falsecxf相关的为true

<module name=orgnfigs/axisdeployer//car load=false/>

<module name=orgnfigs/axisejbdeployer//car load=false/>

<module name=orgnfigs/cxfdeployer//car load=true/>

<module name=orgnfigs/cxfejbdeployer//car load=true/>

重新启动WAS CE服务器

开发一个简单的RESTful Web Service

在Eclipse中创建一个Dynamic Web Project作为Web Service的宿主

选择File>New>Dynamic Web Project

输入Project Name为HelloRestfulService

右击Java Resources src新建一个class其中packageNameInterfaces如下设置

加入如下代码

package comibmwascesamplesjaxwsrest;

import javaioByteArrayInputStream;

import javaxannotationResource;

import javaxservletServletRequest;

import javaxxmlparsersDocumentBuilder;

import javaxxmlparsersDocumentBuilderFactory;

import javaxxmltransformSource;

import javaxxmltransformdomDOMSource;

import javaxxmltransformstreamStreamSource;

import javaxxmlwsBindingType;

import javaxxmlwsProvider;

import javaxxmlwsWebServiceContext;

import javaxxmlwsWebServiceProvider;

import javaxxmlwshandlerMessageContext;

import javaxxmlwshttpHTTPBinding;

import javaxxmlwshttpHTTPException;

import orgwcdomNode;

import orgwcdomNodeList;

import orgxmlsaxInputSource;

@WebServiceProvider

@BindingType (value = HTTPBinding HTTP_BINDING )

public class HelloWorld implements Provider<Source> {

@Resource

protected WebServiceContext wsContext ;

public Source invoke(Source source) {

try {

String targetName = null ;

if (source == null ) {

//Get: Getting input from query string

MessageContext mc = wsContext getMessageContext();

String query = (String) mcget(MessageContext QUERY_STRING );

System out println( Query String = + query);

ServletRequest req = (ServletRequest) mcget(MessageContext SERVLET_REQUEST );

targetName = reqgetParameter( target );

} else {

//POST: Getting input from input box

Node n = null ;

if (source instanceof DOMSource) {

n = ((DOMSource) source)getNode();

} else if (source instanceof StreamSource) {

StreamSource streamSource = (StreamSource) source;

DocumentBuilder builder = DocumentBuilderFactorynewInstance()newDocumentBuilder();

InputSource inputSource = null ;

if (streamSourcegetInputStream() != null ) {

inputSource = new InputSource(streamSourcegetInputStream());

} else if (streamSourcegetReader() != null ) {

inputSource = new InputSource(streamSourcegetReader());

}

n = builderparse(inputSource);

} else {

throw new RuntimeException( Unsupported source: + source);

}

NodeList children = ngetChildNodes();

for ( int i = ; i < childrengetLength(); i++) {

Node child = em(i);

if (childgetNodeName()equals( people )) {

targetName = childgetAttributes()getNamedItem( target )getNodeValue();

break ;

}

}

}

String body = <ns:return xmlns:ns=\\>

+ <ns:HelloWorldResponse> + this sayHello(targetName) + </ns:HelloWorldResponse>

+ </ns:return> ;

return new StreamSource( new ByteArrayInputStream(bodygetBytes()));

} catch (Exception e) {

eprintStackTrace();

throw new HTTPException();

}

}

private String sayHello(String target){

return Hello + target;

}

}

让我们看一看代码中的几个关键点

a) @WebServiceProvider 表明这个Web Service实现了Provider接口可以对XML消息进行完全的处理

b) Provider 是这类Web Service都要实现的接口它只有一个方法需要实现

public abstractjavalangObject invoke(javalangObject arg

c) Source 是交换信息的载体

当Source对象为空时表示是一个GET Request因为这种情况下所有信息是被拼成一个URI的参数并传到这个URI对应的Web Service

否则是一个POST Request其内容会包括在一个Source对象内

另外Response的内容也要放到一个Source对象内

编写webxml

为了使我们前面编写的Web Service能够成功部署到WAS CE中我们需要将如下内容加入到webxml中

<servlet>

<servletname>Hello</servletname>

<servletclass>comibmwascesamplesjaxwsrestHelloWorld</servletclass>

</servlet>

<servletmapping>

<servletname>Hello</servletname>

<urlpattern>/Hello</urlpattern>

</servletmapping>

注意这里只是借用了<servlet>和<servletmapping>标签来帮助暴露Web Service并不是真是要求这个Web Service必须要实现HttpServlet接口

部署运行并测试这个Web Service

右击这个HelloRestfulService工程选择Run As > Run on Server会将其部署到WAS CE中当Status栏变为Synchronized时在Console中会有类似如下信息显示

通过访问如下地址测试使用GET方式调用RESTful Web Service返回的结果

//localhost/HelloRestfulService/Hello?target=Rex

开发一个简单的RESTful Web Service Client

创建一个Dynamic Web Project作为Client

选择File>New>Dynamic Web Project

输入Project Name为HelloRestfulClient

新建一个testgetjsp加入如下内容

<form method=POST action=HelloGetMethodRequester>

Target Name: <input type=text name=target>

<input type=submit value=Submit>

</form>

这个JSP用来为HelloGetMethodRequester Servlet提供参数

创建HelloGetMethodRequester Servlet加入如下内容

protected void doPost(HttpServletRequest request HttpServletResponse response) throws ServletException IOException {

PrintWriter ut = responsegetWriter();

String target = requestgetParameter( target );

String queryRequest = //localhost:/HelloRestfulService/Hello?target= + target;

GetMethod method = new GetMethod(queryRequest);

HttpClient client = new HttpClient();

int statusCode = clientexecuteMethod(method);

if (statusCode != ) { //HttpStatusSC_OK

System err println( Method failed: + methodgetStatusLine());

}

try {

DocumentBuilder builder= DocumentBuilderFactorynewInstance()newDocumentBuilder();

Document queryResponse = builderparse(methodgetResponseBodyAsStream());

XPath xPath = XPathFactorynewInstance()newXPath();

NodeList nodes = (NodeList) xPathevaluate( /return queryResponse XPathConstants NODESET );

for ( int i = ; i < nodesgetLength(); i++) {

// Get eachxpathexpression as a string

String str = (String) xPathevaluate( HelloWorldResponse em(i) XPathConstants STRING );

outprintln( Service return: + str);

}

} catch (Exception e) {

eprintStackTrace();

}

}

在这个Servlet中我们用到了commonscodecjar和commons两个包因此我们需要将它们加入到Build Path中

这两个包在WAS CE的如下目录中可以找到

<WASCE_HOME>\repository\commonscodec\commonscodec\\commonscodecjar

<WASCE_HOME >\repository\commonshttpclient\commonshttpclient\\commons

让我们看一看这段Servlet代码中的一些关键点

a) 首先创建了一个HttpClient对象并运行了GetMethod即使用GET请求如下URI

//localhost/HelloRestfulService/Hello?target= + target

b) 如果成功返回即statusCode为则可以从method对象中得到返回的结果

methodgetResponseBodyAsStream()

c) 因为返回的结果为自定义的一段XML文档所以我们可以使用XPath来处理并输出到页面上

编写部署计划geronimowebxml

为使这个Web Client能够成功部署到WAS CE中我们还需要在geronimowebxml的<environment>中加入如下依赖

<dep:dependencies>

<dep:dependency>

<dep:groupId>commonscodec</dep:groupId>

<dep:artifactId>commonscodec</dep:artifactId>

<dep:version></dep:version>

<dep:type>jar</dep:type>

</dep:dependency>

<dep:dependency>

<dep:groupId>commonshttpclient</dep:groupId>

<dep:artifactId>commonshttpclient</dep:artifactId>

<dep:version></dep:version>

<dep:type>jar</dep:type>

</dep:dependency>

</dep:dependencies>

部署和运行

右击这个HelloRestfulClient工程选择Run As > Run on Server会将其部署到WAS CE中当Status栏变为Synchronized时表示部署成功

在浏览器中打开如下页面

输入Rex并点击Submit可得到如下结果

总结

本文介绍了REST的基本概念以及如何在WAS CE V下开发一个RESTful Web Service和一个使用GET方式的Client如果读者朋友有兴趣的话也可以尝试扩展这个Client如增加testpostjsp和HelloPostMethodRequester Servlet两个文件

testpostjsp包括一个文件上载框用以上传一个XML文件

HelloPostMethodRequester Servlet用于将XML文件以POST方式传送给HelloWorld这个Service

事实上我们的HelloWorld RESTful Web Service已经具备了处理接收一个XML文件的能力

资源链接

·WAS CE及Samples下载

·WAS CE Eclipse Plugin (aka WEP WAS CEs WTP Server Adapter)下载

·WAS CE文档

·WAS CE主页

上一篇:正确使用String类应注意的几点!

下一篇:用JFace和SWT构建简单的应用程序