EMail邮件发送工具.包含Apache Common Email和Vertx Email两个方法

本文介绍了一种使用Java实现的邮件发送工具,包括发送HTML格式邮件的方法,利用Apache Commons Email库和Vert.x框架进行邮件发送的实现细节。该工具支持SMTP认证,并提供了异步发送邮件的功能。

1、发送Email工具本身。

package com.cloudwise.util;


import com.cloudwise.message.EmailMessage;
import com.typesafe.config.Config;
import io.vertx.core.Vertx;
import io.vertx.ext.mail.MailClient;
import io.vertx.ext.mail.MailConfig;
import io.vertx.ext.mail.MailMessage;
import lombok.Delegate;
import org.apache.commons.mail.*;
import org.apache.commons.mail.resolver.DataSourceUrlResolver;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import static com.sun.tools.javac.jvm.ByteCodes.ret;

/**
 * @program 
 * @description: Send Email Util
 * @author: back
 * @create: 2019/08/06 11:50
 */
public class EmailUtil {


    private  final static Config config = ConfigUtils.getConfig();
    
    /**
     * 发送内容格式为HTML的邮件.暂时不含图片资源。
     * 返回值0为成功 1为出现异常
     *
     * @throws EmailException
     * @throws MalformedURLException
     */
    public static Integer sendHTMLEmail(EmailMessage message) {
        try {
            // Create the email message
            HtmlEmail email = new HtmlEmail();
            email.setHostName(config.getString("email.hostname"));
            email.setSSLOnConnect(true);
            email.setCharset("UTF-8");


            email.addTo(message.getTo());
            email.setFrom(message.getFrom() == null ? config.getString("emailFrom")  : message.getFrom());
            email.setSubject(message.getSubject());

            email.setAuthentication(config.getString("email.username"),config.getString("email.password"));

            email.setHtmlMsg(message.getText());

            email.setTextMsg("Your email client does not support HTML messages");

            // 挟带图片资源
//        URL url = new URL("http://www.apache.org/images/asf_logo_wide.gif");
//        String cid = email.embed(url, "Apache logo");
//        email.setHtmlMsg("<html>The apache logo - <img src=\"cid:" + cid + "\"></html>");
            // send the email
            email.send();

            return 0;
        } catch (EmailException e){
            return 1;
        }

    }


    public static CompletableFuture<Integer> sendMailUseVertx(Vertx vertx, EmailMessage emailMessage){

        MailConfig mailConfig = new MailConfig();
        mailConfig.setHostname(config.getString("email.hostname"));
        mailConfig.setUsername(config.getString("email.username"));
        mailConfig.setPassword(config.getString("email.password"));
        String fromEmail = emailMessage.getFrom();


        mailConfig.setPort(config.getInt("email.port"));
        mailConfig.setSsl(true);
//        mailConfig.setTrustAll(true);
//        mailConfig.setStarttls(StartTLSOptions.REQUIRED);
        MailClient mailClient = MailClient.createShared(vertx, mailConfig);
        MailMessage message = new MailMessage();
        message.setFrom(fromEmail);
        message.addHeader("X-Mailer","Microsoft Outlook Express 6.00.2900.2869");
        message.setTo(emailMessage.getTo());
        message.setSubject(emailMessage.getSubject());
        message.setText(emailMessage.getText());

        CompletableFuture<Integer> future = new CompletableFuture<>();


        mailClient.sendMail(message,result->{

            if(result.succeeded()){
                future.complete(0);
            }else{
                future.complete(1);
            }
        });

        return future;
    }

}

2、发送内容信息类

package com.cloudwise.message;


import lombok.Data;

/**
 * @program
 * @description: Send Email Message
 * @author: back
 * @create: 2019/08/06 18:29
 */
@Data
public class EmailMessage {

    private String from;
    private String to;
    private String subject;
    /**
     * 当Simple邮件时此属性正常字符串,Html邮件是填Html的内容
     */
    private String text;

    public EmailMessage(String from, String to, String subject, String text) {

        this.from = from;
        this.to = to;
        this.subject = subject;
        this.text = text;
    }

    public EmailMessage() {
    }
}

3、type safe config简单定义以126邮箱为例

email = {
  hostname = "smtp.126.com"
  port = 
  username = "@126.com"
  password = ""
  emailFrom = "@126.com"
}
2025-12-09 19:32:31.102|ERROR|vmall_car_server|group0-1-thread-1:163|2.0.1.51|7581819637721811752|cse#vmall-mock-alpha-lWX1411448#42bf6d0b37d44accab6f470400e9a8ee|3b10accddd3b43e29464591155d9576a|d6df26ca874340de8e05898f056f5b3e|||Failed to execute HttpServerFilters, operation:vmall-mock-alpha-lWX1411448.CarO2oActivityRpcInterface.queryO2OActivityBySbomCode, request uri:/carO2oActivityRpcInterfaceImpl/queryO2OActivityBySbomCode|org.apache.servicecomb.common.rest.AbstractRestInvocation java.lang.NoSuchMethodError: 'javax.ws.rs.core.Response$StatusType org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx.getStatusType()' at com.huawei.vmall.ssc.client.cse.filter.SscPreHttpServerFilter.beforeSendResponseAsync(SscPreHttpServerFilter.java:123) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.safeInvoke(HttpServerFilterBeforeSendResponseExecutor.java:54) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.doRun(HttpServerFilterBeforeSendResponseExecutor.java:84) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.lambda$doRun$0(HttpServerFilterBeforeSendResponseExecutor.java:87) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887) at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2357) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.doRun(HttpServerFilterBeforeSendResponseExecutor.java:85) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.lambda$doRun$0(HttpServerFilterBeforeSendResponseExecutor.java:87) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887) at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2357) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.doRun(HttpServerFilterBeforeSendResponseExecutor.java:85) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.lambda$doRun$0(HttpServerFilterBeforeSendResponseExecutor.java:87) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887) at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2357) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.doRun(HttpServerFilterBeforeSendResponseExecutor.java:85) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.lambda$doRun$0(HttpServerFilterBeforeSendResponseExecutor.java:87) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887) at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2357) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.doRun(HttpServerFilterBeforeSendResponseExecutor.java:85) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.lambda$doRun$0(HttpServerFilterBeforeSendResponseExecutor.java:87) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887) at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2357) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.doRun(HttpServerFilterBeforeSendResponseExecutor.java:85) at org.apache.servicecomb.common.rest.filter.HttpServerFilterBeforeSendResponseExecutor.run(HttpServerFilterBeforeSendResponseExecutor.java:44) at org.apache.servicecomb.common.rest.AbstractRestInvocation.executeHttpServerFilters(AbstractRestInvocation.java:336) at org.apache.servicecomb.common.rest.AbstractRestInvocation.sendResponse(AbstractRestInvocation.java:330) at org.apache.servicecomb.common.rest.AbstractRestInvocation.sendResponseQuietly(AbstractRestInvocation.java:313) at org.apache.servicecomb.core.handler.impl.ProducerOperationHandler.syncInvoke(ProducerOperationHandler.java:112) at org.apache.servicecomb.core.handler.impl.ProducerOperationHandler.invoke(ProducerOperationHandler.java:63) at org.apache.servicecomb.core.handler.impl.ProducerOperationHandler.handle(ProducerOperationHandler.java:54) at org.apache.servicecomb.core.Invocation.next(Invocation.java:288) at org.apache.servicecomb.qps.ProviderQpsFlowControlHandler.handle(ProviderQpsFlowControlHandler.java:38) at org.apache.servicecomb.core.Invocation.next(Invocation.java:288) at org.apache.servicecomb.common.rest.AbstractRestInvocation.doInvoke(AbstractRestInvocation.java:296) at org.apache.servicecomb.common.rest.AbstractRestInvocation.invoke(AbstractRestInvocation.java:267) at org.apache.servicecomb.common.rest.AbstractRestInvocation.runOnExecutor(AbstractRestInvocation.java:251) at org.apache.servicecomb.common.rest.AbstractRestInvocation.lambda$scheduleInvocation$2(AbstractRestInvocation.java:207) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583)
最新发布
12-10
<think>我们正在解决Java应用中的`java.lang.NoSuchMethodError: javax.ws.rs.core.Response.StatusType`错误。 这个错误通常发生在运行时,表示JVM无法找到一个特定的方法(这里是`javax.ws.rs.core.Response.StatusType`)。主要原因可能是类路径中存在多个不同版本的JAX-RS API库(如Jersey、RESTEasy等)导致版本冲突。 分析: 1. JAX-RS是Java EE的一部分,现在在Jakarta EE中被称为Jakarta RESTful Web Services。 2. 在JAX-RS 2.0中,`Response`类引入了`StatusType`接口。但是,在JAX-RS 1.x中,`Response`类没有这个接口。 3. 因此,这个错误通常是因为应用程序在编译时使用了JAX-RS 2.0(或更高版本)的API,但在运行时却使用了JAX-RS 1.x的库。 解决方案步骤: 步骤1:检查依赖关系 首先,需要确定项目中使用的JAX-RS API实现库的版本。可以使用Maven或Gradle的依赖树命令来检查。 - Maven项目:运行`mvn dependency:tree`并查找与JAX-RS相关的依赖(如`javax.ws.rs:javax.ws.rs-api`,`org.glassfish.jersey.core`等)。 - Gradle项目:运行`gradle dependencies`。 步骤2:排除旧版本 如果发现多个版本的JAX-RS API,需要排除旧版本。例如,在Maven中,可以这样排除: ```xml <dependency> <groupId>com.example</groupId> <artifactId>some-artifact</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> </exclusion> </exclusions> </dependency> ``` 步骤3:确保使用JAX-RS 2.0及以上版本 添加或更新JAX-RS API依赖到2.0及以上版本。例如,对于Maven: ```xml <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.1.1</version> <!-- 或者更高版本 --> </dependency> ``` 步骤4:检查运行时环境 如果应用部署在Java EE应用服务器(如WildFly, TomEE, GlassFish等)中,注意服务器自带的JAX-RS实现版本。有些服务器可能默认使用旧版本。在这种情况下,可能需要: - 升级服务器到支持JAX-RS 2.0的版本(如WildFly 10+,GlassFish 4+)。 - 或者配置服务器使用应用提供的库(例如,在WildFly中可以通过`jboss-deployment-structure.xml`排除服务器模块并引入自己的库)。 步骤5:清理重新构建 在修改依赖后,执行清理并重新构建项目,确保旧版本的库没有残留。 步骤6:使用统一版本的Jakarta REST 如果项目已经迁移到Jakarta EE(即包名从`javax`变为`jakarta`),则需要使用相应的Jakarta REST库: ```xml <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <version>3.1.0</version> <!-- 或更高 --> </dependency> ``` 注意:`javax``jakarta`包不能混用。 常见陷阱: - 多个第三方库传递依赖了不同版本的JAX-RS API。 - 应用服务器自带的JAX-RS实现版本过低。 通过以上步骤,通常可以解决`NoSuchMethodError: javax.ws.rs.core.Response.StatusType`的问题。 §§相关问题§§ 1. 如何解决Java中的`NoClassDefFoundError`错误? 2. Maven中如何排除传递依赖? 3. 如何升级Java EE项目到Jakarta EE? 4. 在WildFly中如何覆盖服务器提供的模块? </think> ### 解决 `java.lang.NoSuchMethodError: javax.ws.rs.core.Response.StatusType` 的方法 此错误通常由 **JAX-RS API 版本冲突** 引起。当编译时使用的 JAX-RS 版本与运行时实际加载的版本不一致时(如编译用 2.x,运行时用 1.x),会因缺失 `StatusType` 接口(JAX-RS 2.0 新增)而报错。以下是逐步解决方案: --- #### 1. **确认依赖版本** - **检查项目依赖**: 使用构建工具命令查看依赖树: ```bash # Maven mvn dependency:tree | grep "jaxrs\|jersey" # Gradle gradle dependencies | grep "jaxrs\|jersey" ``` 重点关注 `javax.ws.rs-api` 或 `jakarta.ws.rs-api` 的版本(JAX-RS 2.0+ 必须)。 - **关键版本要求**: `StatusType` 首次出现在 **JAX-RS 2.0** 中,确保依赖版本 ≥ 2.0: ```xml <!-- Maven 示例 --> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.1.1</version> <!-- 最低需 2.x --> </dependency> ``` [^1] --- #### 2. **解决版本冲突** - **排除旧版本依赖**: 若依赖树中存在多个版本(如 1.x 2.x),在构建文件中排除旧版本: ```xml <!-- Maven 示例:从其他库中排除旧版 JAX-RS --> <dependency> <groupId>com.example</groupId> <artifactId>some-library</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> </exclusion> </exclusions> </dependency> ``` - **强制统一版本**(Maven): 在 `pom.xml` 中显式指定版本: ```xml <properties> <jaxrs.version>2.1.1</jaxrs.version> </properties> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>${jaxrs.version}</version> </dependency> ``` [^2] --- #### 3. **检查运行时环境** - **应用服务器兼容性**: 若部署在 Tomcat/Jetty 等 Servlet 容器,需确保 **应用自带的 JAX-RS 库版本 ≥ 2.0**。 若使用 WildFly/JBoss 等 Java EE 服务器,检查服务器支持的 JAX-RS 版本: ```bash # WildFly 示例:查看模块版本 $WILDFLY_HOME/bin/jboss-cli.sh --command="ls deployment=YOUR_APP.war :read-resource" ``` - WildFly 10+ 默认支持 JAX-RS 2.x[^3]。 - **避免服务器自带库冲突**: 在 `WEB-INF/jboss-deployment-structure.xml`(WildFly)中排除旧模块: ```xml <jboss-deployment-structure> <deployment> <exclusions> <module name="javaee.api" /> <!-- 排除旧版 EE API --> </exclusions> </deployment> </jboss-deployment-structure> ``` --- #### 4. **迁移到 Jakarta EE 命名空间**(可选) - 若使用 Jakarta EE 9+,包名从 `javax.ws.rs` 改为 `jakarta.ws.rs`: ```xml <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <version>3.1.0</version> <!-- Jakarta EE 9+ --> </dependency> ``` - 需同步修改代码中的 import 语句: ```java // 替换前 import javax.ws.rs.core.Response; // 替换后 import jakarta.ws.rs.core.Response; ``` --- #### 5. **验证解决方案** - 清理构建并重新部署: ```bash mvn clean package # Maven gradle clean build # Gradle ``` - 使用 `-verbose:class` 参数启动应用,检查加载的 JAX-RS 类版本: ```bash java -verbose:class -jar your-app.jar | grep "javax/ws/rs/core/Response" ``` --- ### 总结流程图 ```mermaid graph TD A[出现 NoSuchMethodError] --> B[检查依赖树] B --> C{存在冲突?} C -->|是| D[排除旧版本依赖] C -->|否| E[检查运行时环境] D --> F[强制统一版本] E --> G{应用服务器自带旧版本?} G -->|是| H[排除服务器模块] G -->|否| I[升级项目依赖] H --> J[重新构建部署] F --> J I --> J J --> K[问题解决] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值