将Java服务公开为Web服务

本教程解决了开发人员面临的最实际的情况。 大多数时候,我们可能需要将某些现有服务公开为Web服务。 在项目生命周期的不同阶段可能会遇到这种情况。 如果这是初始阶段,那么您几乎是安全的,您可以为此做好充分的准备。 但是,将要发生的情况是,仅在一半的开发完成或系统在生产环境中运行后才提出此要求。

如果在最初的项目体系结构中未考虑Web服务,这将不会有些棘手。 您可能涉及不同种类的项目体系结构,并使用不同种类的技术。 作为开发人员,由于可能存在很多依赖关系,因此您不能更改某些体系结构和配置。

Internet上的大多数教程都介绍了创建Web服务的基本内容。 有时,“ Hello world”应用程序或某个时候可能是像这样的简单计算器。 这些教程非常有助于您对Web服务有基本的了解。 但是现实世界的场景要比这复杂十倍,并且在遵循此类教程时必须面对困难。
实际情况

在本教程中,我将解释“我们如何真正解决您的主管提出的现实世界的要求”。 我将解释最近遇到的相同情况。
一个医疗保健组织在岛上经营着许多药房。 他们有一个处理所有库存,定价和开票,发行药房物品等的Web应用程序。他们需要通过Web服务公开药房物品的价格,以便药房中的客户应用程序可以通过Web服务访问这些产品。 他们的Web应用程序是在struts2,Spring和休眠的集成环境中开发的。 它具有所有Spring管理的DAO类以及服务类。 该应用程序使用spring的自动接线技术,组件扫描,事务管理等。在这种背景下,我需要将药房价格作为Web服务公开。 那就是我们当前药房服务中的某些方法需要通过网络服务公开给外部。

我将向您展示,如何通过对现有项目进行最小的修改来实现这种要求。
附加图书馆

我将使用JAX-WS实现Web服务。 我在项目中使用了JAX-WS 2.2。 您可以从此处下载所需的JAX-WS版本。 这提供了一些可用于生成Web服务及其客户端内容的工具。 下载所需的库版本后,将其解压缩到本地计算机中的某些位置。 我已将其放在主文件夹中。
即:/home/semika/jaxws-ri-2.2

实施网络服务

我已经有了用于Web的内部使用的Spring托管服务类和用于药房项目的DAO类。 那些没有暴露在外面。 假设,我们需要公开findAll()方法,该方法以Web服务的形式返回“ PharmacyService”接口的“ PharmacyItem”列表。

为了方便起见,我将向您展示“ PharmacyServiceImpl” java类,该类用于执行常规药房项目操作。 这是通常的Springman豆。 请记住,此类的方法目前只能用于我们的Web应用程序的内部操作。 这些没有作为Web服务公开。
PharmacyServiceImpl.java

/*** */
package com.slauto.service.pharmacy.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.slauto.exceptions.ServiceException;
import com.slauto.model.pharmacy.PharmacyItem;
import com.slauto.persist.pharmacy.api.PharmacyItemDao;
import com.slauto.service.pharmacy.api.PharmacyItemService;/*** @author semika**/
@Service('pharmacyItemService') 
public class PharmacyItemServiceImpl implements PharmacyItemService {@Autowiredprivate PharmacyItemDao pharmacyItemDao;@Overridepublic List<Pharmacyitem> findAll() throws ServiceException {return pharmacyItemDao.findAllPharmacyItems();}
}

如您所见,我在实现类中具有“ PharmacyItemDao”的自动连线实例。 众所周知,这是一个Spring托管服务实现类。

接下来,我们将为上面的spring托管服务bean实现Web服务端点类,以将其方法公开为Web服务方法。 为了清楚起见,我创建了一个单独的类作为Web服务端点。

PharmacyItemServiceEndPoint.java

package com.slauto.service.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.slauto.exceptions.DataAccessException;
import com.slauto.model.pharmacy.PharmacyItem;
import com.slauto.service.pharmacy.api.PharmacyItemService;/*** @author semika**/
@WebService(serviceName='pharmacyItemService') 
public class PharmacyItemServiceEndPoint {@WebMethodpublic List<Pharmacyitem> findAll() throws DataAccessException {ApplicationContext context = new ClassPathXmlApplicationContext('applicationContext.xml'); PharmacyItemService pharmacyItemService = (PharmacyItemService)context.getBean('pharmacyItemService');return pharmacyItemService.findAll();}
}

如您在这里看到的,我正在使用'pharmacyItemService'bean,我们的Web应用程序使用它来访问相关的服务方法。 “ pharmacyItemService”是一种常用的Spring mange bean,用于执行日常药房项目操作。 没什么特别的。 特别注意,指示此类的@WebService@WebMethod注释用作Web服务端点。

在这里,我通过应用程序上下文获取服务类实例。 此外,我们可以通过扩展spring提供的' SpringBeanAutowiringSupport '的端点类,来使用Spring自动连接Web服务端点类。 在这种情况下,我们不需要像上面所做的那样创建应用程序上下文实例。 我无法完成这项工作,这就是为什么我使用了上述技术。

使用“ SpringBeanAutowiringSupport ”,在部署Web服务时(说明如下),我遇到了一个异常,很难解决。 所以我选择了这项技术。 无论如何,我不喜欢上面的内容:)。
生成Web服务

我正在使用JAX-WS提供的apt , wsgen和wsimport工具来生成JAX-WS服务中使用的可移植工件。 “ build.xml ”文件的相关ant目标如下。
您可能需要在“ build.xml”文件顶部声明的以下属性。

属性:

<property name='tomcat.home'        value='/home/semika/apache-tomcat-7.0.25' />
<property name='jaxws.home'         value='/home/semika/jaxws-ri-2.2' />
<property name='build.classes.home' value='${basedir}/WEB-INF/classes' />
<property name='java.home'          value='/home/semika/java/jdk1.6.0_30'>

类路径:

<path id='project.class.path'><pathelement location='${java.home}/../lib/tools.jar' /><fileset dir='${jaxws.home}/lib'><include name='*.jar' /></fileset><pathelement location='${basedir}/WEB-INF/classes' /><fileset dir='${basedir}/WEB-INF/lib' includes='*.jar' />
</path>

JAX-WS apt工具目标:

<target name='apt' depends='javac'><taskdef name='apt' classname='com.sun.tools.ws.ant.Apt'><classpath refid='project.class.path' /></taskdef><apt fork='true'debug='true'verbose='true'destdir='${basedir}/WEB-INF/classes'sourcedestdir='${basedir}/WEB-INF/src'sourcepath='${basedir}/WEB-INF/src'><classpath><path refid='project.class.path' /></classpath><option key='r' value='${basedir}/WEB-INF' /><source dir='${basedir}/WEB-INF/src'><include name='**/*.java'/></source></apt>
</target>

如果您想进一步了解JAX-WS提供的apt工具,请查看this 。 运行apt目标时,它将扫描源路径(src文件夹),并为使用@WebService注释的类生成所需的* .class和* .java文件。 在这种情况下,适用于“ PharmacyItemServiceEndPoint.java”。 如果查看“ PharmacyItemServiceEndPoint”所在的包,则可以看到它创建了一个名为“ jaxws ”的新包。 在该程序包中,我可以看到以下三个Java文件。
DataAccessExceptionBean.java
FindAll.java FindAllResponse.java

这些类由该工具生成,并且根据您的服务实现和Web服务涉及的相关类而有所不同。 实际上,您不必担心这些生成的东西。
同样,您可以在/ WEB-INF / classes文件夹下看到相关的* .class文件。

JAX-WS wsgen工具目标:

<target name='wsgen' depends='apt'> <taskdef name='wsgen' classname='com.sun.tools.ws.ant.WsGen'><classpath path='project.class.path'/></taskdef><wsgen xendorsed='true'sei='com.slauto.service.ws.PharmacyItemServiceEndPoint'destdir='${basedir}/WEB-INF/classes'      resourcedestdir='${wsdl.dir}'sourcedestdir='${basedir}/WEB-INF/src'      keep='true'verbose='true'genwsdl='true'><classpath refid='project.class.path'/></wsgen>
</target>

wsgen工具将为我们的端点Web服务类生成WSDL文件。 运行此目标后,请查看$ {wsdl.dir}的位置。 您可以看到我们的WSDL文件已经生成。 如果您想进一步了解JAX-WS提供的wsgen工具,请研究this 。
部署Web服务

我想用通常的服务器启动来部署Web服务。 因此,我必须将以下配置添加到web.xml文件中。

<listener><listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet><servlet-name>pharmacyItemService</servlet-name><servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>pharmacyItemService</servlet-name><url-pattern>/pharmacyItemService</url-pattern>
</servlet-mapping>

正如我之前告诉您的那样,当部署具有从' SpringBeanAutowiringSupport '扩展的端点类的Web服务时,它给出了一个例外。 因此,我决定通过应用程序上下文获取服务bean。 如果您能解决这种情况,请直接发布。

而且,您需要在WEB-INF文件夹下创建sun-jaxws.xml并声明Web服务端点,如下所示。

<?xml version='1.0' encoding='UTF-8'?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>    <endpointname='pharmacyItemService'implementation='com.slauto.service.ws.PharmacyItemServiceEndPoint'url-pattern='/pharmacyItemService'/>
</endpoints>

我正在使用apache tomcat 7.0.25部署Web服务。 您需要告诉tomcat启动tomcat时可以在哪里找到JAX-WS库。 您可以编辑位于CATALINA_HOME / conf文件夹中的“ catalina.properties ”文件。 查找common.loader属性。 大多数情况如下。

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar

对其进行如下修改。

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,/home/semika/jaxws-ri-2.2/lib/*.jar

如您所见,我已经在逗号分隔列表的末尾添加了我的JAX-WS库路径。 这些类对tomcat内部类和tomcat容器中部署的所有Web应用程序均可见。 现在,您可以将.war文件复制到tomcat的webapps文件夹中,然后启动tomcat。 您的Web服务应已部署。 为了确认您的Web服务已正确部署,您可以检查它的WSDL 。 对于WSDL文件,您应该以以下格式检查URL。

http:// localhost:8080 / <您的上下文名称> / pharmacyItemService?wsdl

如果您可以在浏览器中看到WSDL文件,则说明您已经完成,您已经成功部署了Web服务。

生成Web服务客户端

现在,我们已经部署了Web服务。 接下来,我们将看到如何编写客户端类以使用Java程序访问Web服务。 您可以创建一个简单的Java项目,并在其中使用以下build.xml文件。 我已经放置了完整的build.xml文件用于客户端生成。 我正在使用JAX-WS附带的wsimport工具来生成Web服务客户端工件。

<?xml version='1.0' encoding='utf-8' ?>
<project name='WS-client' default='wsimport' basedir='.'><property name='jaxws.home'  value='/home/semika/jaxws-ri-2.2' /><property name='java.home' value='/home/semika/java/jdk1.6.0_30'/><path id='jaxws.classpath'><pathelement location='${java.home}/../lib/tools.jar' /><fileset dir='${jaxws.home}/lib'><include name='*.jar' /></fileset></path><target name='wsimport'> <taskdef name='wsimport' classname='com.sun.tools.ws.ant.WsImport'><classpath path='jaxws.classpath'/></taskdef><wsimport   xendorsed='true'debug='true'verbose='true'keep='true'destdir='src'package='com.slauto.service'wsdl='http://localhost:8080/slautomanage/pharmacyItemService?wsdl'></wsimport></target>
</project>

如果您想进一步了解wsimport工具,可以查看this 。 运行上述目标后,只需看看在wsimport属性下指定的包即可。 您将看到生成的一组Java文件。 您可以将它们编译并捆绑到单个client.jar文件中,并且可以与需要此Web服务的任何Java项目一起使用。
我创建了一个非常简单的java类,以通过Web服务获取药房信息。

客户端程序

package com.slauto.client;import java.util.List;import com.slauto.service.PharmacyItem;
import com.slauto.service.PharmacyItemService;
import com.slauto.service.PharmacyItemServiceEndPoint;/*** @author semika**/
public class Client {/*** @param args*/public static void main(String[] args) {PharmacyItemService p = new PharmacyItemService();PharmacyItemServiceEndPoint ep = p.getPharmacyItemServiceEndPointPort();List<PharmacyItem> pharmacyItems = ep.findAll();for (PharmacyItem pharmacyItem : pharmacyItems) {System.out.println(pharmacyItem.getCode()); }}}

太好了吗? 运行该课程后,您将看到显示的药房商品代码列表。 这些药房信息通过具有复杂环境的Web应用程序部署的Web服务来传递。
就是本教程中的内容。 希望对您有所帮助,如果您从本教程中学习到一些东西,请不要忘了发表评论。

参考: 如何将现有服务公开为Web服务? 从我们的JCG合作伙伴 Semika loku kaluge在Code Box博客上获得。


翻译自: https://www.javacodegeeks.com/2012/06/expose-java-service-as-web-service.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372436.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git服务器维护 备份,gitlab服务运维,备份与恢复 - 橙子柠檬's Blog

gitlab服务运维工作Gitlab-ctl 使用gitlab-ctl start #启动服务gitlab-ctl stop #停止服务gitlab-ctl restart #重启服务检查服务的日志信息gitlab-ctl tail redis #检查redis的日志gitlab-ctl tail postgresql #…

angular js实现开关效果

功能&#xff1a;实现点击排序&#xff0c;再点击排倒序。 实现方法如下 方法一&#xff1a;定义变量实现点击切换true或false&#xff0c;代码为&#xff1a; $scope.lidata [ {"name":"Terry","age":12}, {&qu…

使用TestNG的弹簧测试支持

TestNG是一个测试框架&#xff0c;旨在涵盖所有类别的测试&#xff1a;单元&#xff0c;功能&#xff0c;端到端&#xff0c;集成等。 它包括许多功能&#xff0c;例如灵活的测试配置&#xff0c;对数据驱动测试的支持&#xff08;使用DataProvider&#xff09;&#xff0c;强大…

Entity Framework - 理清关系 - 基于外键关联的单向一对一关系

注&#xff1a;本文针对的是 Entity Framework Code First 场景。 之前写过三篇文章试图理清Entity Framework中的一对一关系&#xff08;单相思&#xff08;单向一对一&#xff09;, 两情相悦&#xff08;双向一对一&#xff09;, 两情相悦-续&#xff09;&#xff0c;但当时理…

微信社交小程序服务器,Day12-微信小程序实战-交友小程序-搭建服务器与上传文件到后端...

要搞一个小型的cms内容发布系统因为小程序上线之后&#xff0c;直接对数据库进行操作的话&#xff0c;慧出问题的&#xff0c;所以一般都会做一个管理系统&#xff0c;让工作人员通过这个管理系统来对这个数据库进行增删改查微信小程序其实给我们提供了这样的能力了(也就是可以…

java go

熟练掌握java技术&#xff0c;对多线程、数据结构有清晰的认识&#xff1b; 熟悉MySQL/Oracle数据库&#xff0c;熟悉关系数据库应用设计开发&#xff1b; 熟悉Spring/MyBatis/Freemarker等一种或者多种框架&#xff1b; java基础扎实&#xff0c;熟练掌握目前主流的开源框架&a…

了解如何解决OSGI捆绑包

我想回顾一下OSGI包如何解决并使用Apache Karaf进行演示。 Karaf是基于Apache Felix内核的功能齐全的OSGI容器&#xff0c;并且是Apache ServiceMix集成容器的基石。 对于第一部分&#xff0c;我将讨论OSGI框架如何解决捆绑包。 在第二部分中&#xff0c;我将使用Apache Karaf演…

文件共享服务器imac,iMac怎么在网络上共享设备windows文件夹和服务 | MOS86

本章通过向您展示如何在网络和Mac和Windows计算机之间共享文件&#xff0c;文件夹和设备&#xff0c;帮助您充分利用您的iMac网络连接。→使用Macs共享文件和文件夹使用AirDrop和文件共享→与Windows 7计算机共享文件→设置共享权限→使用共享表快速在线共享文件→共享和访问网…

【转】 简单理解Socket

题外话 前几天和朋友聊天&#xff0c;朋友问我怎么最近不写博客了&#xff0c;一个是因为最近在忙着公司使用的一些控件的开发&#xff0c;浏览器兼容性搞死人&#xff1b;但主要是因为这段时间一直在看html5的东西&#xff0c;看到web socket时觉得很有意思&#xff0c;动手写…

.NET基础

.NET C# ASP.NET关系&#xff1a;.NET是一个平台&#xff0c;提供程序运行的虚拟机环境和类库。 C#是.Net平台上的一种语言&#xff0c;其他语言还有VB.NET PowerShell等。 ASP.NET是在.NET下的网站开发技术。 安装.NET FrameWork就可以运行。VS集成安装了.NET FrameWork. 控制…

业务活动监视器(BAM)2.0带来的革命

生产兼具精益和企业价值的中间件是一项艰巨的工作。 它要么不存在&#xff0c;要么需要创新的思维&#xff08;很多&#xff09;&#xff0c;并且需要在实现中反复进行。 业务风险很大&#xff0c;但是如果您做对了&#xff0c;它就会使您领先于其他任何公司。 这就是为什么我们…

oracle销售服务器吗,oracle 服务器 版本

oracle 服务器 版本 内容精选换一换Atlas 800 训练服务器(型号 9010)安装上架、服务器基础参数配置、安装操作系统等操作请参见《Atlas 800 训练服务器 用户指南 (型号9010)》。Atlas 800 训练服务器(型号 9010)适配操作系统如表1所示。请参考表2下载驱动和固件包。Atlas 800 训…

Vue组件间通信:一个例子学会Vue组件-Vue.js学习总结)(转载)

详情请点击 http://www.jianshu.com/p/9ad1ba89a04b转载于:https://www.cnblogs.com/zhongjiang/p/6694459.html

必填字段的自定义JSF验证器

实现EditableValueHolder接口的JSF组件具有两个属性“ required”和“ requiredMessage” –一个标志&#xff0c;指示用户需要输入/选择非空值&#xff0c;以及一个用于验证消息的文本。 我们可以使用它&#xff0c;但是它不够灵活&#xff0c;我们不能直接在视图中&#xff0…

java 转码%2f%_JS和JAVA中常用的编码转码函数

js中escape,encodeURI,encodeURIComponent函数和unescape,decodeURI和decodeURIComponent函数的功能1.escape方法对String对象编码,escape方法返回一个包含了"转义序列"的字符串值。除了ASCII字母和数字&#xff0c;以及这几个符号 *-/._外(共有1052769个字符不会被编…

mybatis 下划线转驼峰配置

一直以来&#xff0c;在sqlmap文件中&#xff0c;对于数据库中的下划线字段转驼峰&#xff0c;我们都是通过resultmap来做的&#xff0c;如下&#xff1a; <resultMap id"ISTableStatistics" type"com.medsoft.perfstat.pojo.ISTableStatistics" > &…

Python练习-迭代器-模拟cat|grep文件

代码如下: 1 # 编辑者&#xff1a;闫龙2 def grep(FindWhat):3 fopen("a.txt","r",encoding"utf8")#以只读的方式打开a.txt文件4 while True:5 try:6 fline next(f).strip()#由于File类型本身就是一个迭代器,所以直…

Spring和JSF集成:转换器

使用任何Web框架时&#xff0c;都不可避免地需要将用户输入的数据从String为其他类型。 尽管Spring和JSF在设计和功能上确实有很大的不同&#xff0c;但它们都具有转换器策略来处理此问题。 让我们从春天开始。 Spring 3引入了一个全新的转换框架&#xff0c;该框架允许将任何类…

nacos配置ap_Nacos 1.0.0 功能预览

本文来自于我的个人主页&#xff1a;Nacos 1.0.0 功能预览&#xff0c;转载请保留链接 ;)Nacos 1.0.0 是正式 GA 的版本&#xff0c;在架构、功能和API设计上进行了全方位的重构和升级&#xff0c;1.0.0版本标志着Nacos的架构已经稳定&#xff0c;API列表最终确定。升级到1.0.0…

poj 2229 Sumsets

题目大意&#xff1a; 一个数由2的幂次数的和构成&#xff0c;问有几种构成方式&#xff1f; 主要是找规律 代码如下 1 #include <cstdio>2 #include <cstring>3 int n;4 #define M 10000000005 int dp[1000002];6 7 int main(int argc, char const *argv[])8 {9 …