java web服务_将Java服务公开为Web服务

java web服务

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

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

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

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

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

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

实施网络服务

我已经有了Spring托管的服务类和DAO类(用于药房项目),该类已在Web应用程序内部使用。 那些没有暴露在外面。 假设,我们需要公开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服务时(说明如下),我遇到了一个异常,很难解决。 所以我选择了这项技术。 无论如何,我不喜欢上面使用的内容:)。
生成网络服务

我正在使用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

java web服务

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

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

相关文章

python文件打开方式详解——a、a+、r+、w+区别

第一步 排除文件打开方式错误&#xff1a;r只读&#xff0c;r读写&#xff0c;不创建w新建只写&#xff0c;w新建读写&#xff0c;二者都会将文件内容清零&#xff08;以w方式打开&#xff0c;不能读出。w可读写&#xff09;**w与r区别&#xff1a;r&#xff1a;可读可写&#…

程序员的工作周报该怎么写?

大多数公司都有写周报的要求&#xff0c;为什么要写周报&#xff1f;很多流于形式的周报&#xff0c;会让员工感到厌烦。特别是程序员&#xff0c;你让他写代码可以&#xff0c;写这种篇幅稍微大点的文字&#xff0c;简直要了他的命。周报作为一种文字载体&#xff0c;是下级向…

一个快速生成元素背景的 React 组件

在开发过程中&#xff0c;我们经常会遇到使用背景的地方&#xff0c;比如登录页面&#xff0c;用户信息页面&#xff0c;封面图…… 寻找契合业务主题的背景十分耗费精力&#xff0c;总觉得做的背景不合适&#xff0c;如果直接用图片呢&#xff0c;逻辑是比较简单&#xff0c;但…

引入ReactiveInflux:用于Scala和Java的无阻塞InfluxDB驱动程序,支持Apache Spark

我很高兴宣布Pygmalios开发的ReactiveInflux的第一个发行版。 InfluxDB错过了Scala和Java的非阻塞驱动程序。 不变性&#xff0c;可测试性和可扩展性是ReactiveInflux的关键功能。 加上对Apache Spark的支持&#xff0c;它是首选武器。 https://github.com/pygmalios/reactive…

python之路_前端基础之Bootstrap 组件

文档内容参考地址&#xff1a;http://v3.bootcss.com/components/ 一、图标 如下例&#xff0c;Star文本前有一个空格&#xff1a; <button type"button" class"btn btn-default btn-lg"><span class"glyphicon glyphicon-star" aria-h…

内卷之下,前端工程师如何自救

近两年的职场内卷现象越来越严重&#xff0c;996 工作制在各大公司已经很常见&#xff0c;甚至有更甚者&#xff0c;告诉你我们公司的前端是如何内卷的&#xff1f;为了数字化转型&#xff0c;公司要为产品平台化打造一个办公协同的在线管理系统&#xff0c;来规范化项目流程管…

Java核心技术 卷1 多线程----线程安全的集合(4)

如果多线程要并发的修改一个数据结构&#xff0c;例如散列表&#xff0c;那么很容易会破坏这个数据结构。一个线程可能要开始向表中插入一个新元素。假定在调整散列表各个桶之间的链接关系的过程中&#xff0c;被剥夺了控制权。如果另一个线程也开始遍历同一个链表&#xff0c;…

如何快速实现 Wordpress 博客域名更换?

如题&#xff0c;如何快速更换使用 Wordpress 搭建的网站、博客的域名&#xff0c;除了在域名服务商那更换域名的解析和 web服务器端的配置外&#xff0c;还应该从数据库端做些什么&#xff1f;熟悉 Wordpress 的用户都知道在 Wordpress 后台&#xff0c;设置 --> 常规 里有…

java jigsaw_是从Java 8启动的Project Jigsaw吗?

java jigsaw在马克雷因霍尔德 &#xff08; Mark Reinhold &#xff09;在他的《 项目拼图&#xff1a;火车晚点 》一文中提出“将项目拼图推迟到Java 9的下一个发行版中”。 他解释了这样做的原因&#xff1a;“仍然存在一些重大的技术挑战”&#xff0c;并且“没有足够的时间…

浮动—春联(文字竖直排列)

<div id"main"><div class"top">李白</div><div class"left">明月几时有</div><div class"right">把酒问青天</div> </div> 1 #main{2 height: 540px;3 …

UE 动画系统框架介绍及使用

UE 动画系统介绍 UE 动画系统介绍 UE 动画系统介绍一 动画基础介绍1.1 骨架1.2 骨架网格体1.3 动画序列1.4 动画蓝图二 状态机三 动画混合Blend3.1 动画混合3.2 混合空间BlendSpace3.3 惯性混合四 瞄准偏移AimOffset五 叠加动画Additive Animation六 动画蒙太奇 Animation Mont…

了解下广告计费模式CPC、CPA和CPM

目前各大广告平台最常见的广告计费模式分别有CPC、CPA、CPM。例如知乎、头条、百度、腾讯等各类平台投放广告&#xff0c;基本都离不开这几种广告计费方式。由于博客流量日渐见好&#xff0c;最近也申请了谷歌的广告的流量主&#xff0c;所以有必要了解下这几种广告模式&#x…

JUnit 5 –设置

2015年11月&#xff0c; JUnit Lambda团队展示了他们的原型 。 此后&#xff0c;该项目更名为JUnit 5&#xff0c;并于2016年2月发布了Alpha版本。我们将在一系列简短文章中对其进行探讨&#xff1a; 设定 基本 建筑 条件 注射 … 本章讨论JUnit 5的设置&#xff0c;以便…

Python非递归实现二叉树的后续遍历

leetcode 145. Binary Tree Postorder Traversal 思路一&#xff1a; 使用一个栈stack保存经过的根结点&#xff0c;另一个栈flag保存每个结点的右子树是否遍历&#xff1b;如果根结点存在&#xff0c;结点入栈&#xff0c;并把结点的右子树遍历结果置为0&#xff0c;代表没遍历…

删除对象中值为 null 或者 undefined 的属性

针对对象属性的操作&#xff0c;往往用到遍历。如何遍历对象的所有属性&#xff0c;有一种方法是 Object.entries(obj) 将属性名添加到一个数组中&#xff0c;然后来操作数组。 第一种方法 const removeNullUndefined (obj) > Object.entries(obj).reduce((a, [k, v]) &g…

《Linux命令行与shell脚本编程大全 第3版》Linux命令行---55

以下为阅读《Linux命令行与shell脚本编程大全 第3版》的读书笔记&#xff0c;为了方便记录&#xff0c;特地与书的内容保持同步&#xff0c;特意做成一节一次随笔&#xff0c;特记录如下&#xff1a;转载于:https://www.cnblogs.com/guochaoxxl/p/7888785.html

如何在 VS Code 中创建自己的代码片段

在项目开发中&#xff0c;我们经常需要新建文件&#xff0c;而这些初始化这些文件又需要敲出很多相同的代码&#xff0c;比如我们新建一个 .vue 的文件&#xff0c;需要我们在写正式的功能代码之前&#xff0c;完成以下初始化代码&#xff1a; <script setup langts> &l…

java基础(第七章课后作业)03

1 package shuzu;2 3 import java.util.Scanner;4 5 public class ZuoYe03 {6 7 public static void main(String[] args) {8 Scanner meng00new Scanner(System.in);9 int []numsnew int[10];//定义一个输入10个整数的数组 10 int []countnew int…

如何使用 Apifox 来管理测试你的接口

日常开发&#xff0c;你是使用 Postman 来测试接口&#xff0c;还是用接口文档生成工具 Swagger&#xff0c;最近发现了一个很好用的工具 Apifox&#xff0c;集API 文档、API 调试、API Mock、API 自动化测试功能为一体&#xff0c;兼客户端和 Web 端的强大的功能。 主要界面如…

登录之后更新导航

用上下文处理器app_context_processor定义函数获取session中保存的值返回字典 app.context_processor def mycontext():username session.get(user)if username:return {username:username}else:return {} 在父模板中更新导航&#xff0c;插入登录状态判断代码。注意用{% ... …