javax.mail 实现邮件发送

首先,附上官网文档,请自行查阅:

https://docs.oracle.com/javaee/7/api/javax/mail/package-summary.html

常用邮箱服务器以及对应端口:

sina.com:  
POP3服务器地址:pop3.sina.com.cn(端口:110)  
SMTP服务器地址:smtp.sina.com.cn(端口:25)   
  
sinaVIP:  
POP3服务器:pop3.vip.sina.com (端口:110)  
SMTP服务器:smtp.vip.sina.com (端口:25)  
  
sohu.com:  
POP3服务器地址:pop3.sohu.com(端口:110)  
SMTP服务器地址:smtp.sohu.com(端口:25)  
  
126邮箱:  
POP3服务器地址:pop.126.com(端口:110)  
SMTP服务器地址:smtp.126.com(端口:25)  
  
139邮箱:  
POP3服务器地址:POP.139.com(端口:110)  
SMTP服务器地址:SMTP.139.com(端口:25)  
  
163.com:  
POP3服务器地址:pop.163.com(端口:110)  
SMTP服务器地址:smtp.163.com(端口:25)  
  
QQ邮箱   
POP3服务器地址:pop.qq.com(端口:110)  
SMTP服务器地址:smtp.qq.com (端口:25)  
  
QQ企业邮箱  
POP3服务器地址:pop.exmail.qq.com (SSL启用 端口:995)  
SMTP服务器地址:smtp.exmail.qq.com(SSL启用 端口:587/465)  
  
yahoo.com:  
POP3服务器地址:pop.mail.yahoo.com  
SMTP服务器地址:smtp.mail.yahoo.com  
  
yahoo.com.cn:  
POP3服务器地址:pop.mail.yahoo.com.cn(端口:995)  
SMTP服务器地址:smtp.mail.yahoo.com.cn(端口:587  
  
HotMail  
POP3服务器地址:pop3.live.com (端口:995)  
SMTP服务器地址:smtp.live.com (端口:587)  
  
gmail(google.com)  
POP3服务器地址:pop.gmail.com(SSL启用 端口:995)  
SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587)  
  
263.net:  
POP3服务器地址:pop3.263.net(端口:110)  
SMTP服务器地址:smtp.263.net(端口:25)  
  
263.net.cn:  
POP3服务器地址:pop.263.net.cn(端口:110)  
SMTP服务器地址:smtp.263.net.cn(端口:25)  
  
x263.net:  
POP3服务器地址:pop.x263.net(端口:110)  
SMTP服务器地址:smtp.x263.net(端口:25)  
  
21cn.com:  
POP3服务器地址:pop.21cn.com(端口:110)  
SMTP服务器地址:smtp.21cn.com(端口:25)  
  
Foxmail:  
POP3服务器地址:POP.foxmail.com(端口:110)  
SMTP服务器地址:SMTP.foxmail.com(端口:25)  
  
china.com:  
POP3服务器地址:pop.china.com(端口:110)  
SMTP服务器地址:smtp.china.com(端口:25)  
  
tom.com:  
POP3服务器地址:pop.tom.com(端口:110)  
SMTP服务器地址:smtp.tom.com(端口:25)  
  
etang.com:  
POP3服务器地址:pop.etang.com  
SMTP服务器地址:smtp.etang.com  

邮件的发送过程大致如下:

创建一个 Session 对象。
Session 对象创建一个 Transport 对象 /Store 对象,用来发送 / 保存邮件。
Transport 对象 /Store 对象连接邮件服务器。
Transport 对象 /Store 对象创建一个 Message 对象 ( 也就是邮件内容 ) 。
Transport 对象发送邮件; Store 对象获取邮箱的邮件。

发送文本邮件最简代码,官方文档给出的如下:

       //配置文件
        Properties props = new Properties();
        //设置邮箱服务器,有对应的默认端口
        props.put("mail.smtp.host", "my-mail-server");
        //获取一个邮箱session实例
        Session session = Session.getInstance(props, null);

        try {
            //邮件发送工具类参数对象
            MimeMessage msg = new MimeMessage(session);
            //设置发件人信息
            msg.setFrom("me@example.com");
            //设置收件人信息
            msg.setRecipients(Message.RecipientType.TO,
                    "you@example.com");
            //设置邮件主题
            msg.setSubject("JavaMail hello world example");
            //设置邮件时间
            msg.setSentDate(new Date());
            //设置邮件内容
            msg.setText("Hello, world!\n");
            //发送邮件,验证邮箱账号和密码
            Transport.send(msg, "me@example.com", "my-password");
        } catch (MessagingException mex) {
            System.out.println("send failed, exception: " + mex);
        }

以上,就可以完成一个简单的邮件发送。

接下来,我们做一下优化,使其能够成为易于维护的工具类。

先建一个maven工程,pom.xml如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>spring-boot</groupId>
    <artifactId>spring-study</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--spring-boot-starter-test 起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>LATEST</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.29</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

我们最主要是添加 spring-boot-starter-mail 的起步依赖来实现邮件发送的功能。

MailAuthenticator ,用于用户登录认证

package demo.mail;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class MailAuthenticator extends Authenticator {

    /**
     * 用户名
     */
    private String userName;
    /**
     * 密码
     */
    private String userPass;

    public MailAuthenticator() {
    }

    public MailAuthenticator(String userName, String userPass) {
        this.userName = userName;
        this.userPass = userPass;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, userPass);
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPass() {
        return userPass;
    }

    public void setUserPass(String userPass) {
        this.userPass = userPass;
    }

    @Override
    public String toString() {
        return "MailAuthenticator{" +
                "userName='" + userName + '\'' +
                ", userPass='" + userPass + '\'' +
                '}';
    }
}

MailBean,邮件发送bean

package demo.mail;

import java.util.List;

public class MailBean {

    /**
     * 发件人地址
     */
    private String fromAddress;
    /**
     * 收件人地址
     */
    private String toAddress;
    /**
     * 邮箱用户名
     */
    private String userName;
    /**
     * 邮箱用户名密码
     */
    private String userPassword;
    /**
     * 多个收件人
     */
    private List<String> recipients;
    /**
     * 邮件主题
     */
    private String subject;
    /**
     * 邮件内容
     */
    private MailContent content;

    public String getFromAddress() {
        return fromAddress;
    }

    public void setFromAddress(String fromAddress) {
        this.fromAddress = fromAddress;
    }

    public String getToAddress() {
        return toAddress;
    }

    public void setToAddress(String toAddress) {
        this.toAddress = toAddress;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public List<String> getRecipients() {
        return recipients;
    }

    public void setRecipients(List<String> recipients) {
        this.recipients = recipients;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public MailContent getContent() {
        return content;
    }

    public void setContent(MailContent content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "MailBean{" +
                "fromAddress='" + fromAddress + '\'' +
                ", toAddress='" + toAddress + '\'' +
                ", userName='" + userName + '\'' +
                ", userPassword='" + userPassword + '\'' +
                ", recipients=" + recipients +
                ", subject='" + subject + '\'' +
                ", content=" + content +
                '}';
    }
}

Mail配置常量

package demo.mail;


public class MailConstant {

    /**
     * smtp 服务器
     */
    public static final String MAIL_SMTP_HOST = "mail.smtp.host";
    /**
     * smtp服务器的端口
     */
    public static final String MAIL_SMTP_PORT = "mail.smtp.port";
    /**
     * 如果为true,STARTTLS则在发出任何登录命令之前,启用命令(如果服务器支持)将连接切换到TLS保护的连接。
     * 请注意,必须配置适当得信任存储,以便客户端信任服务器得证书。默认为false
     */
    public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
    /**
     * 如果为true,则尝试使用AUTH命令认证用户。默认为false.
     */
    public static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
    /**
     * 指定使用指定套接字工厂时要连接的端口。如果未设置,将使用默认端口。
     */
    public static final String MAIL_SMTP_SOCKETFACTORY_PORT = "mail.smtp.socketFactory.port";
    /**
     * 如果设置为true,则无法使用指定的套接字工厂类创建套接字将导致使用java.net.Socket该类创建套接字。默认为true.
     */
    public static final String MAIL_SMTP_SOCKETFACTORY_FALLBACK = "mail.smtp.socketFactory.fallback";
    /**
     * Transport对象才会向SMTP服务器提交用户认证信息
     */
    public static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
    /**
     * 发件人地址
     */
    public static final String MAIL_FROM = "mail.from";
    /**
     * ssl 被smtp认证
     */
    public static final String MAIL_SMTP_SSL_TRUST = "mail.smtp.ssl.trust";
    /**
     * 用户名
     */
    public static final String MAIL_USERNAME = "mail.username";
    /**
     * 密码
     */
    public static final String MAIL_CRYPTOGRAM = "mail.password";

    /**
     * 私有构造器,坏味道
     */
    private MailConstant() {
        //do nothing
    }
}

MailContent,用于存储邮件内容:

package demo.mail;

public class MailContent {

    /**
     * 邮件主题
     */
    private String subject;
    /**
     * 内容时间
     */
    private String date;
    /**
     * 内容
     */
    private String content;

    public MailContent() {
    }

    public MailContent(String subject, String date, String content) {
        this.subject = subject;
        this.date = date;
        this.content = content;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "MailContent{" +
                "subject='" + subject + '\'' +
                ", date='" + date + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

MailHtml,将邮件内容转换为Html形式

package demo.mail;

public class MailHtml {

    public static String getMailHtml(String date,String sub,String content){
        StringBuilder sb = new StringBuilder();
        sb.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">")
                .append("<html>")
                .append("<head>")
                .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">")
                .append("<title>邮件</title>")
                .append("<style type=\"text/css\">")
                .append("table{width:100%;height:100%;border-collapse:collapse;border:none;}")
                .append("table td{border:solid gray 1px;}")
                .append(".td_1{width:20%;text-align:center;background-color:#cce8cf;}")
                .append("</style>")
                .append("</head>")
                .append("<body>")
                .append("<table>")
                .append("<tr style='height:15%;'><td class=\"td_1\">时间</td><td>"+date+"</td></tr>")
                .append("<tr style='height:15%;'><td class=\"td_1\">标题</td><td>"+sub+"</td></tr>")
                .append("<tr><td class=\"td_1\">内容</td><td>"+content+"</td></tr>")
                .append("</table>")
                .append("</body>")
                .append("</html>");
        return sb.toString();
    }

    private MailHtml() {
        throw new IllegalAccessError("MailHtml class");
    }
}

MailProperties,用于获取邮件配置文件信息

package demo.mail;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ResourceBundle;

public class MailProperties {

    private static Logger logger = LoggerFactory.getLogger(MailProperties.class);

    private static final String BONDEL_NAME = "mail";

    private static final ResourceBundle bundel = ResourceBundle.getBundle(BONDEL_NAME);


    public static String getValue(String key) {

        //参数校验
        if (StringUtils.isBlank(key)) {
            System.out.println("发生了未知异常!");
        }

        String value = null;
        try {
            value = bundel.getString(StringUtils.trim(key));
        } catch (Exception e) {
            logger.warn(String.format("value not existed: %s", key), e);
        }

        return StringUtils.isBlank(value) ? StringUtils.EMPTY : value;
    }

}

MailSend,邮件发送类:

package demo.mail;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.List;
import java.util.Properties;

public class MailSend {

    private static final Logger logger = LoggerFactory.getLogger(MailSend.class);

    /**
     * 发送邮件的props 文件
     */
    private static Properties props;
    /**
     * 邮件登录 权限验证
     */
    private static MailAuthenticator authenticator;
    /**
     * 邮件服务器session
     */
    private static Session session;
    /**
     * 发送邮件 工具
     */
    private static Transport transport;
    /**
     * 邮件附件(目前还不支持附件上传的功能)
     */
    private static Multipart multipart;

    /**
     * 初始化
     *
     */
    static {

        // 初始化props
        props = new Properties();
        props.put(MailConstant.MAIL_SMTP_HOST, MailProperties.getValue(MailConstant.MAIL_SMTP_HOST));
        props.put(MailConstant.MAIL_SMTP_PORT, MailProperties.getValue(MailConstant.MAIL_SMTP_PORT));
        props.put(MailConstant.MAIL_SMTP_STARTTLS_ENABLE, MailProperties.getValue(MailConstant.MAIL_SMTP_STARTTLS_ENABLE));
        props.put(MailConstant.MAIL_SMTP_AUTH, MailProperties.getValue(MailConstant.MAIL_SMTP_AUTH));
        props.put(MailConstant.MAIL_SMTP_SOCKETFACTORY_PORT, MailProperties.getValue(MailConstant.MAIL_SMTP_SOCKETFACTORY_PORT));
        props.put(MailConstant.MAIL_SMTP_SOCKETFACTORY_FALLBACK, MailProperties.getValue(MailConstant.MAIL_SMTP_SOCKETFACTORY_FALLBACK));
        props.put(MailConstant.MAIL_TRANSPORT_PROTOCOL, MailProperties.getValue(MailConstant.MAIL_TRANSPORT_PROTOCOL));
        props.put(MailConstant.MAIL_FROM, MailProperties.getValue(MailConstant.MAIL_FROM));
        props.put(MailConstant.MAIL_SMTP_SSL_TRUST, MailProperties.getValue(MailConstant.MAIL_SMTP_SSL_TRUST));
        // 验证
        authenticator = new MailAuthenticator(MailProperties.getValue(MailConstant.MAIL_USERNAME),
                MailProperties.getValue(MailConstant.MAIL_CRYPTOGRAM));
        // 创建session
        session = Session.getDefaultInstance(props, authenticator);

    }

    /**
     * 群发邮件
     *
     * @param recipients 收件人们
     * @param subject 主题
     * @param content 内容
     * @throws AddressException
     * @throws MessagingException
     */
    @SuppressWarnings("static-access")
    protected static void send(List<String> recipients, String subject, MailContent content) {
        try {
            // 创建mime类型邮件
            final MimeMessage message = new MimeMessage(session);
            // 设置发信人
            message.setFrom(new InternetAddress(authenticator.getUserName()));
            // 设置收件人们
            final int num = recipients.size();
            InternetAddress[] addresses = new InternetAddress[num];
            for (int i = 0; i < num; i++) {
                addresses[i] = new InternetAddress(recipients.get(i));
            }
            message.setRecipients(Message.RecipientType.TO, addresses);
            // 设置主题
            message.setSubject(subject);
            // 设置邮件内容
            message.setContent(MailHtml.getMailHtml(content.getDate(), content.getSubject(), content.getContent()),
                    "text/html;charset=utf-8");
            // 发送时间
            message.setSentDate(new Date());
            message.saveChanges();
            // 发送
            logger.info("===protocol is ============" +  props.get(MailConstant.MAIL_TRANSPORT_PROTOCOL) );
            transport = session.getTransport(((String) props.get(MailConstant.MAIL_TRANSPORT_PROTOCOL)).trim());
            // 真正的连接邮件服务器并进行身份验证

            transport.connect((String.valueOf(props.get(MailConstant.MAIL_SMTP_HOST)).trim()),
                    Integer.parseInt(String.valueOf(props.get(MailConstant.MAIL_SMTP_PORT))), authenticator.getUserName(),
                    authenticator.getUserPass());
            transport.send(message);
        } catch (Exception e) {
            logger.error("mailsend send error : ", e);
        } finally {
            try {
                transport.close();
            } catch (MessagingException e) {
                logger.error("mailsend send close error : ", e);
            }
        }
    }
}

SendMailThread,用于控制最大并发

package demo.mail;

public class SendMailThread implements Runnable{


    private MailBean mailBean;

    public SendMailThread(MailBean mailBean) {
        this.mailBean = mailBean;
    }

    public MailBean getMailBean() {
        return mailBean;
    }

    public void setMailBean(MailBean mailBean) {
        this.mailBean = mailBean;
    }

    @Override
    public void run() {
        MailUtil.send(mailBean);
    }
}

MailUtil,邮件发送工具类,将邮件发送类注入静态方法

package demo.mail;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class MailUtil {

    private static final Logger logger = LoggerFactory.getLogger(MailUtil.class);
    //线程池核心线程数
    private static final int COREPOOLSIZE = 1;
    //线程池最大线程数
    private static final int MAXMUMPOOLSIZE = 10;
    //超过核心线程数,空闲线程等待任务的最长时间 单位 毫秒,0 的意思是 空闲线程直接销毁
    private static final long KEEPALIVETIME = 0;
    //当线程池中线程数等于核心线程数时,新创建的线程任务放到阻塞队列中去
    private static final BlockingQueue<Runnable> EMAIL_QUEUE = new LinkedBlockingDeque<>(10);

    ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXMUMPOOLSIZE, KEEPALIVETIME,
            TimeUnit.SECONDS, EMAIL_QUEUE, new ThreadPoolExecutor.AbortPolicy());

    public static void send(MailBean mailBean) {
        try {
            MailSend.send(mailBean.getRecipients(), mailBean.getSubject(), mailBean.getContent());
        } catch (Exception e) {
            logger.error("mailutil error : ", e);
        }finally {
            logger.info("邮件发送  成功了!");
        }
    }
}

.properties,配置文件

#smtp服务器
mail.smtp.host=smtp.163.com
#smtp服务器的端口
mail.smtp.port=25
#如果为true,STARTTLS则在发出任何登录命令之前,启用使用命令(如果服务器支持)将连接切换到TLS保护的连接。请注意,必须配置适当的信任存储,以便客户端信任服务器的证书。默认为false。
mail.smtp.starttls.enable=true
#如果为true,则尝试使用AUTH命令认证用户。默认为false。
mail.smtp.auth=true
#指定使用指定套接字工厂时要连接的端口。如果未设置,将使用默认端口。
mail.smtp.socketFactory.port=25
#如果设置为true,则无法使用指定的套接字工厂类创建套接字将导致使用java.net.Socket该类创建套接字 。默认为true。
mail.smtp.socketFactory.fallback=false
#Tranport对象才会向SMTP服务器提交用户认证信息
mail.transport.protocol=smtp
mail.from=xxx@163.com
#ssl被smtp认证
mail.smtp.ssl.trust=smtp.163.com
#邮箱用户名
mail.username=xxx@163.com
#邮箱密码
mail.password=password

单元测试,要将邮件服务器,和验证发件人和密码改成对应的

package demo.mail;

import demo.DemoApplication;
import org.junit.Test;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = DemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)
public class MailUtilTest {

    @Autowired
    private MailUtil mailUtil;

    @Test
    public void send() throws Exception {
        MailBean mailBean = new MailBean();
        List<String> internetAddresses = new ArrayList<>();
        internetAddresses.add("xiaomingtongxie@163.com");
        MailContent mailContent = new MailContent();
        mailContent.setContent("邮件内容为:23333333");

        mailBean.setSubject("测试邮件发送");
        mailBean.setRecipients(internetAddresses);
        mailBean.setContent(mailContent);
        mailUtil.send(mailBean);

    }

}

感谢您的阅读,如果觉得对您有用,记得点赞哦。

先附上源码地址,博客有时间再更新

https://github.com/xiaomingtongxie/springboot-study.git

码云地址:

https://gitee.com/xiaomingnevermind/springboot-study.git

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

使用openjdk9-alpine运行springboot2

本文主要研究怎么在docker的java9镜像上运行springboot2并精简jdk.

1621
来自专栏程序员的SOD蜜

使用Topshelf创建自宿主的Windows服务程序

在传统的Windows服务开发过程中,需要添加一个服务安装程序,里面写安装,启动和停止服务等逻辑。现在,使用TopSelf可以简化这个过程。具体请看官网说明: ...

2105
来自专栏丑胖侠

Java中InetAddress和InetSocketAddress的区别

在Java中InetAddress和InetSocketAddress看起来很相似,用来描述IP地址和主机名称。当然,它们也支持使用常规方法来检查地址:回环地址...

1948
来自专栏菩提树下的杨过

gradle项目中资源文件的相对路径打包处理技巧

开发java application时,不管是用ant/maven/gradle中的哪种方式来构建,通常最后都会打包成一个可执行的jar包程序,而程序运行所需的...

4865
来自专栏Hongten

java开发_java小程序_邮死你(yousini)_源码下载

==========================================================

882
来自专栏猿天地

spring boot整合dubbox进行服务拆分

Dubbo是一个来自阿里巴巴的开源分布式服务框架,当当根据自身的需求,为Dubbo实现了一些新的功能,包括REST风格远程调用、Kryo/FST序列化等等。并...

8539
来自专栏史上最简单的Spring Cloud教程

SpringBoot非官方教程 | 第二十二篇: 创建含有多module的springboot工程

这篇文章主要介绍如何在springboot中如何创建含有多个module的工程,栗子中含有两个 module,一个作为libarary. 工程,另外一个是主工程...

1959
来自专栏写写代码吃吃瓜

简单的NDK开发

1296
来自专栏程序之美

第十三节 资源服务和认证服务通信,校验token

1) 设置RestTemplate,默认RestTemplate有些格式无法解析,配置相关解析器

482
来自专栏WindCoder

Dubbo入门-简易配置

想看分布式的东西好久了,目前的公司用不到,只能自己去网上找相关的,看到最多的Dubbo,于是趁着今天有时间自己照着一些教程自己配置了个基础的demo,顺便放出来...

733

扫码关注云+社区