欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

程序员文章站 2022-05-05 13:17:30
...

1.SOA(面向服务的架构)架构模式现在十分的流行。WebService是SOA的一种实现方式,本文将用发送邮件这个服务来展示一下WebService是如何工作的。

2.WebService就是提供服务的网络API,它给你提供服务的结构,调用方只需要负责调用服务即可。这里其实就涉及到了一些问题,首先是如何调用?服务肯定是运行在服务器上的,要想远程调用服务器上的服务就需要和服务器通信,和服务器通信就需要通信协议,比如大名鼎鼎的TCP协议。以及封装了它的上层HTTP协议等等。SOAP协议和REST协议就是两种在实现WebService的通信协议,有了这个协议,服务器会把自己的提供的服务的配置信息写到这个协议里,客户端的调用解析这个协议然后调用即可。

3.首先是SOAP协议。这个协议看上去有点复杂:首先给出整个Demo的项目结构:

                                               【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

这里服务和客户端写在了一起,无所谓了,反正知识Demo,客服端和服务器的分离也是分分种的事情,懒得每次都要切屏了。

首先,是提供服务的类:mailService.这个类提供了发送邮件的服务:

                                              【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

具体看一下实现:

                          【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

比如sendEmail这个函数,传入地址和内容,然后调用邮件发送工具的发送函数,发送邮件。注意这里的格式,首先是@WebService这个注解,表明这里的类是即将被发布成WebService类,类中要提供服务的函数,需要注解为@WebMethod。

其他三个函数类似。(啥,邮箱工具的发送函数是怎么写的?,后边会统一发出来,这个不是重点,服务的实现方式并不是重点,重点是我们怎么实现服务的发布和调用)。

然后服务写好了之后,很重要,怎么发布?

import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService
public class PublishServer {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String url="http://localhost:9090/Service/mailService";
		Endpoint.publish(url,new mailService());
		System.out.print("public Success");
	}
}

调用Endpoint的发布函数,把服务发送到固定的端口。当然了,这里可以直接启动Tomcat,把服务丢进Tomcat内,Tomcat启动的时候就会自动的把服务给发布了。

    发布完成以后,服务端会有一个.WSDL的文件。叫做WebService描述文档,这个就是基于SOAP协议的文档,怎么看这个文档呢?启动服务(我这里直接启动主函数就行,如果是在Tomcat内,就启动tomcat),然后到发布的端口上去看:

【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

注意看一下地址栏的网址,就是服务所在的地址+?WSDL,意思就是请求WSDL,这是一个基于get方法的请求方法,不多说了。可以看到这个WSDL文档,这是WebService的核心。这个文档内描述了这个服务的所有信息,客户端正是由于知道了这些信息才能正确的实现调用。

      那么客户端如何调用呢?首先需要生成客户端,生成客户端其实就是在解析这个WSDL文档,根据这个文档在客户端建立服务端服务的视图,通过这个视图来调用。解析WSDL文档有很多种方式,这里提供一个简单的,打开cmd输入:

 wsimport -s D:\DataBase\AWSTestEclipse\WebServiceProject\src -p mailClient -keep http://localhost:9090/Service/mailService?wsdl

解释一下,-s后的就是这个项目src所在的文件夹,-p后是目标代码生成的包名,-keep就是WSDL文档的地址,然后刷新一下文件目录结构。

                                      【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

就生成了这些东西。这是怎么实现的?其实是JDK里面有一个专门解析WSDL文档的JAR包。具体叫啥好像就是wsiport.jar.有了这个,就可以尽情的调用了。

      客户端的调用我写了两种方式,由于懒只介绍一种吧。采用JSP+Servlet的调用。JSP前端传回信息,后端接受信息调用服务。

                      【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

核心代码:由于在客户端我们有了服务器的视图,就相当于把服务端的代码给重现了,然后直接new对应的类,调用对应的方法提供服务。完事了,好像很简单。其实这里的底层实现我想了一下,大胆猜测,就是JAVA的RMI,简直和远程方法调用一摸一样。所以软件的发展好像就是再不断重复?????

     然后SOAP就说完了。然后是REST。

     REST可能就是JAVA注解的应用吧(啥叫注解???随便理解一下就是注入并解释,JAVA的动态注入大名鼎鼎,这也算是一个应用吧)

     正题:

还是看一下Demo的目录结构:

                                        【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

    还是用REST实现一个邮件发送服务:首先需要一些外部JAR包。

                                      【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

这个文件夹我后边会上传打github,当然自己下也可以。把里面的所有的jar包导入成外部jar包,并且在WEB-INF/lib复制一份

                                       【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

为啥要复制到lib下因为汤姆猫启动的时候,只会加载lib下的外部jar包,所以以后遇到tomcat报错无法找到XX类,就去把包复制进就完事了。

然后继续写服务类:

【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

hai还是刚才的sendEmail函数,这里有几个很重要的注解,首先是最上面的@Path("/SendService")注解,这里其实就是在定义这个类的路径。然后函数上的三个注解,@GET指的是网络请求方法,@Path()定义了这个函数相对于类的路径,最后一个Prodeces我也没仔细看。函数参数的注解,额,没啥好说的,很normal,就是动态注入时候用的。

最后写一下配置文件,这个很重要,但是格式几乎就是固定的:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>CalculatorREST</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Jersey RESTful Application</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>mypackage</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey RESTful Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>HandleQuery</servlet-name>
    <servlet-class>test.HandEmail</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>HandleQuery</servlet-name>
    <url-pattern>/test1</url-pattern>
  </servlet-mapping>
  
  
  
</web-app>

除去我得Servlet(HandleQuery)的配置,上边的都是这个服务的配置,其实大多都不变,只需要配置一下包名:

                  【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

服务写完,直接在项目名上右键,run起来,tomcat启动。

         客户端如何调用?其实很简单,REST之所以使用@Path注解一直在注解路径,就是为了向外部暴露自己方法的路径,只要是沿着路径找到它,然后再把参数给注入进去就完事了。Tomcat通过反射注入参数,实现调用。比如服务器启动之后,直接再浏览器输入:http://localhost:8080/TestRest/rest/SendService/[email protected]&payload=test

【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

 

解析一下这个地址:首先TestRest是项目名,rest表明我们用rest协议,SendService呢?

【JAVA 编程】基于SOAP协议和REST协议的邮件发送服务

再看一下这张图,我们把类注解为SendService,所以他会找到这个类,后边的也是一样的,找到sendEmail这个方法,然后把参数注入。完成调用。

常见问题:

(1)javax.email找不到?哥哥你要导入啊!!!!!,官网下一个??

(2)SOAP协议发布的时候,显示areadyBind???之类的,如果你已经run了一次了,这个端口就被bind了,解决方案:换一个或者从起

(3)SOAP协议是@WebSevice之类的注解失败??该注解的地方注解一下。。。。。别偷懒

(4)REST协议web.xml配置文件总是出错???复制我上边哪个,别瞎改。。。。

(5)REST协议时,注意把javax.email也给加到lib里

github地址:https://github.com/wsyingang/SA/tree/master/SendEmail