Spring02-模拟用户登录,发送邮件-G04

Spring02-模拟用户登录,发送邮件

一.注解方式注入 bean

对于 bean 的注入,除了使用 xml 配置以外,注解的配置简化开发的速度,使程
序看上去更简洁。对于注解的解释,spring
对于注解有专门的解释器,对定义的注解
进行解析,实现对应 bean 对象的注入,反射技术实现。
1.加入 spring-aop jar 包 spring-aop-4.3.2.RELEASE.jar
2.Xml 配置: 加入 context 命名空间 和 xsd 地址\

  1. 添加<context:annotation-config/> 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解注入配置 -->
  <context:annotation-config/>


对于 bean 的注入常用注解类型
@Autowired 属性字段或 set 方法上
@Resource 属性字段上或 set 方法上
区别: @Autowired 默认按 bean 的类型匹配 可以修改 按名称匹配 和
@Qualifier 配合使用
@Resource 默认按名称进行装配, 名称可以通过 name 属性进行指定, 如果没
有指定 name 属性, 当注解写在字段上时, 默认取字段名进行匹配注入, 如果
注解写在 setter 方法上默认取属性名进行装配。 当找不到与名称匹配的 bean
时才按照类型进行装配。 但是需要注意的是,如果 name 属性一旦指定,
就只会按照名称进行装配。
推荐使用@Resource 注解是属于 J2EE 的,减少了与 spring 的耦合。

二、 Spring Ioc 容器自动扫描管理 bean
实际的开发中,bean 的数量非常多,采用手动配置 bean 的方式已无法满足生
产需要,spring 这时候同样提供了扫描的方式,对扫描到的 bean
对象统一进行管理,
简化开发配置,提高开发效率。
<context:component-scan base-package="com.shsxt"/>
**不需要再配置
<context:annotation-config/>

同时对于被 spring 管理的 bean 类的定义上需要加入对应的注解定义

开发中建议(开发中的一种约定)
Dao 层:@Repository
Service 层:@Service
视图控制层:@Controller
如果对于开发的类实在不明确到底属于哪个层,可以使用@Component 注解定义。

三、 借助 spring 模拟用户登陆流程

image.png

1.配置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>com.shsxt</groupId>
  <artifactId>spring01</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>spring01</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>

  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
  </build>
</project>


2.配置spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 开启包扫描 -->
    <context:component-scan base-package="com.shsxt"/>

    <!--<bean id="userController" class="com.shsxt.controller.UserController" lazy-init="true"></bean>-->
    <bean id="userController" class="com.shsxt.controller.UserController" scope="prototype"></bean>
</beans>


3.Dao 层 根据用户名查询用户记录UserDao

@Repository
public class UserDao {

    private final String NAME="zhangsan";
    private final String PWD="123456";

    public User queryUserByName(String name){
        User user = null;
        if(name.equals(NAME)){
            user = new User();
            user.setName(NAME);
            user.setPwd(PWD);
        }
        return user;
    }
}


4.新建po-->User类

public class User {
    private String name;
    private String pwd;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}


5.Service 业务判断处理UserService调用Dao层,进行参数校验

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public ResultInfo login(String name, String pwd){
        /**
         * 1. 参数校验
         * 2. 查询用户
         * 3. 比较密码是否正确
         */
        ResultInfo info = new ResultInfo();
        if(null==name || "".equals(name)){
            info.setCode(300);
            info.setMsg("用户名为空");
            return info;
        }
        if(null==pwd || "".equals(pwd)){
            info.setCode(300);
            info.setMsg("密码为空");
            return info;
        }

        User user = userDao.queryUserByName(name);
        if(null==user){
            info.setCode(300);
            info.setMsg("用户不存在");
            return info;
        }

        if(pwd.equals(user.getPwd())){
            info.setCode(200);
            info.setMsg("登陆成功");
            return info;
        }else{
            info.setCode(300);
            info.setMsg("用户名或密码不正确");
            return info;
        }
    }
}



6.定义业务处理返回消息模型新建model包ResultInfo存储查询信息

public class ResultInfo {

    private Integer code;
    private String msg;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "ResultInfo{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                '}';
    }
}


*7.controller层UserController调用service层加入登录功能方法*

//@Lazy
//@Controller
public class UserController {

    public UserController() {
        System.out.println("UserController init...");
    }

    @Autowired
    private UserService userService;

    public ResultInfo login(String name, String pwd){
        return userService.login(name, pwd);
    }


}


8.Junit 通过 junit 进行测试UserControllerTest测试类

public class UserControllerTest {
    @Test
    public void login() throws Exception {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring.xml");
        UserController userController = (UserController) context.getBean("userController");
        ResultInfo info = userController.login("zhangsan", "123456");
        System.out.println(info);
    }

    @Test
    public void login02() throws Exception {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring.xml");

        System.out.println(context.isSingleton("userController"));

        System.out.println(context.getBean("userController"));
        System.out.println(context.getBean("userController"));
    }


测试结果

四、 Bean 的作用域问题
默认情况下,我们从 spring 容器中拿到的对象均是单例的,对于 bean
的作用
域类型如下:
1、 singleton 作用域

image.png

注意: lazy-init 是懒加载, 如果等于 true 时作用是指 spring
容器启动的时候不
会去实例化这个 bean, 而是在程序调用时才去实例化. 默认是 false 即 spring
容器启\动时实例化.
默认情况下,被管理的 bean 只会 IOC 容器中存在一个实例,对于所有获取该
Bean 的操作 Spring 容器将只返回同一个 Bean。

**容器在启动的情况下就实例化所有 singleton 的 bean 对象,并缓存与容器中
单例的好处:
1)提前发现潜在的配置问题
2)Bean 对象存在于缓存中,使用时不用再去实例化 bean,加快程序运行效率
**什么类型的对象适合作为单例对象来使用呢? service,dao,action 等
一般来说对于无状态或状态不可改变的
对象适合使用单例模式(什么是无状态或状态
不可改变)
实际上对象状态的变化往往均是由于属性值得变化而引起的,比如 user 类 年龄
属性会有变化 属性年龄的变化一般会引起 user
对象状态的变化。对于我们的程序来
说,无状态对象 没有实例变量的存在,保证了线程的安全性,service
层业务对象即是
无状态对象。线程安全的。

2、 prototype 作用域


image.png

通过 scope=" prototype" 设置 bean 的类型 ,每次向 Spring 容器请求获取
Bean 都返回一个全新的 Bean,相对于"singleton"来说就是不缓存
Bean,每次都是
一个根据 Bean 定义创建的全新 Bean。

<bean id="userController" class="com.shsxt.controller.UserController" scope="prototype"></bean>  
不是单例


3、 Web 应用中的作用域(request、 session、 globalsession)
request 作用域:表示每个请求需要容器创建一个全新 Bean。比如提交表单
的数据必须是对每次请求新建一个 Bean
来保持这些表单数据,请求结束释放这些数据。
session 作用域:表示每个会话需要容器创建一个全新
Bean。比如对于每个用
户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该 Bean
作用
域配置为 session 级别。
globalSession:类似于 session 作用域,其用于 portlet(Portlet 是基于
Java
的 Web 组件,由 Portlet 容器管理,并由容器处理请求,生产动态内容)环境的
web 应
用。如果在非 portlet 环境将视为 session 作用域。
配置方式和基本的作用域相同,只是必须要有 web 环境支持,并配置相应的
容器监听器或拦截器从而能应用这些作用域.

五、 Bean 的生命周期
1.Bean 的定义
对比已经学过的 servlet 生命周期(容器启动装载并实例化 servlet
类,初始化
servlet,调用 service 方法,销毁 servlet)。
同样对于 spring 容器管理的 bean 也存在生命周期的概念
**在 Spring 中,Bean 的生命周期包括 Bean 的定义、初始化、使用和销毁 4
个阶段
**在 Spring 中,通常是通过配置文档的方式来定义 Bean
的。在一个配置文档中,可以
定义多个 Bean。
2、 Bean 的初始化
Spring bean 初始化有两种方式:

I.在配置文档中通过指定 init-method 属性来完成。
II.实现 org.springframework.beans.factory.InitializingBean 接口。
Bean 对象实例化过程是在 spring 容器初始化 时被实例化的,但也不是不可改
变的,可以通过 lazy-init="true" 属性延迟 bean
对象的初始化操作,此时再调用
getbean 方法时才会进行 bean 的初始化操作

<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl"
init-method="init" >

3.Bean 的使用
I.使用 BeanFactory
II.使用 ApplicationContext
4.Bean 的销毁
实现销毁方式(spring 容器会维护 bean 对象的管理,可以指定 bean 对象的销
毁所要执行的方法)\

<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl" init
method="init" destroy-method="destroy">
</bean>

通过 AbstractApplicationContext 对象,调用其 close 方法实现 bean
的销毁过程。\

AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("spring
application.xml");
ctx.close();

六、 JavaMail 概述
JavaMail 是由 Sun 定义的一套收发电子邮件的 API, 不同的厂商可以提供自
己的实现类。 但它并没有包含在 JDK 中, 而是作为 JavaEE 的一部分。
厂商所提供的 JavaMail 服务程序可以有选择地实现某些邮件协议, 常见的
邮件协议包括:
SMTP: 简单邮件传输协议, 用于发送电子邮件的传输协议;
POP3: 用于接收电子邮件的标准协议;
IMAP: 互联网消息协议, 是 POP3 的替代协议。
这三种协议都有对应 SSL 加密传输的协议, 分别是 SMTPS, POP3S 和 IMAPS。
除 JavaMail 服务提供程序之外,JavaMail 还需要 JAF(JavaBeans Activation
Framework)来处理不是纯文本的邮件内容, 这包括 MIME(多用途互联网邮件扩
展 ) 、 URL 页 面 和 文 件 附 件 等 内 容 。 另 外 , JavaMail 依 赖
JAF(JavaBeans
Activation Framework), JAF 在 Java6 之后已经合并到 JDK 中, 而 JDK5
之前需
要另外下载 JAF 的类库。

[6.1、 协议介绍]{.smallcaps}
1、 介绍
在研究 JavaMail API 的细则之前, 首先需要对于 API 用到的协议有个认识。
对于 java mail 来说用到的协议有一下 4 种:
SMTP
POP
IMAP
MIME
2、 SMTP
简单邮件传输协议(Simple Mail Transfer Protocol, SMTP) 由 RFC 821
定义。
它定义了发送电子邮件的机制。 在 JavaMail API 环境中, 您基于 JavaMail
的程
序将和您的公司或因特网服务供应商的(Internet Service Provider's,
ISP's)
SMTP 服务器通信。 SMTP 服务器会中转消息给接收方 SMTP 服务器以便最终让
用户经由 POP 或 IMAP 获得。

3、 POP
POP 代表邮局协议(Post Office Protocol) 。 目前用的是版本 3, 也称
POP3,
RFC 1939 定义了这个协议。 POP 是一种机制,
因特网上大多数人用它得到邮件。
它规定每个用户一个邮箱的支持。 这就是它所能做的,
而这也造成了许多混淆。
使用 POP3 时, 用户熟悉的许多性能并不是由 POP 协议支持的, 如查看有几封
新邮件消息这一性能。 这些性能内建于如 Eudora 或 Microsoft Outlook
之类的程
序中, 它们能记住一些事, 诸如最近一次收到的邮件,
还能计算出有多少是新的。
所以当使用 JavaMail API 时, 如果您想要这类信息, 您就必须自己算。
4、 IMAP
IMAP 是更高级的用于接收消息的协议。 在 RFC 2060 中被定义, IMAP 代表
因特网消息访问协议(Internet Message Access Protocol) , 目前用的是版本
4,
也称 IMAP4。 在用到 IMAP 时, 邮件服务器必需支持这个协议。 不能仅仅把使
用 POP 的程序用于 IMAP, 并指望它支持 IMAP 所有性能。 假设邮件服务器支
持 IMAP, 基于 JavaMail 的程序可以利用这种情况 ---
用户在服务器上有多个文
件夹(folder) , 并且这些文件夹可以被多个用户共享。
因为有这一更高级的性能, 您也许会认为所有用户都会使用 IMAP。 事实并
不是这样。 要求服务器接收新消息, 在用户请求时发送到用户手中,
还要在每个
用户的多个文件夹中维护消息。 这样虽然能将消息集中备份,
但随着用户长期的
邮件夹越来越大, 到磁盘空间耗尽时, 每个用户都会受到损失。 使用 POP,
就能
卸载邮件服务器上保存的消息了。
5、 MIME
MIME 代表多用途因特网邮件扩展标准(Multipurpose Internet Mail
Extensions) 。 它不是邮件传输协议。 但对传输内容的消息、
附件及其它的内容
定义了格式。这里有很多不同的有效文档: RFC 822、RFC 2045、RFC 2046 和
RFC
2047。 作为一个 JavaMail API 的用户, 您通常不必对这些格式操心。
无论如何,
一定存在这些格式而且程序会用到它。
[6.3、 JavaMail 的关键对象]{.smallcaps}
JavaMail 对收发邮件进行了高级的抽象, 形成了一些关键的的接口和类,
它们构成了程
序的基础, 下面我们分别来了解一下这些最常见的对象。

Properties:属性对象
由于 JavaMail 需要和邮件服务器进行通信, 这就要求程序提供许多诸如服务
器地址、 端口、 用户名、 密码等信息, JavaMail 通过 Properties
对象封装这些属
性西信息。 如下面的代码封装了两个属性信息:
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.sina.com.cn");
props.put("mail.smtp.auth", "true");
针对不同的的邮件协议, JavaMail 规定了服务提供者必须支持一系列属性,
下表是针对 SMTP 协议的一些常见属性(属性值都以 String 类型进行设置,
属性
类型栏仅表示属性是如何被解析的) :

image.png

其他几个协议也有类似的一系列属性, 如 POP3 的 mail.pop3.host、
mail.pop3.port 以及\IMAP 的 mail.imap.host、 mail.imap.port 等。

Session:会话对象
Session 是一个很容易被误解的类, 这归咎于混淆视听的类名。
千万不要以为这
里的 Session 像 HttpSession 一样代表真实的交互会话, 但创建 Session
对象时,
并没有对应的物理连接, 它只不过是一对配置信息的集合。 Session
的主要作用
包括两个方面:

1) 接收各种配置属性信息: 通过 Properties 对象设置的属性信息;
2) 初始化 JavaMail 环境: 根据 JavaMail 的配置文件, 初始化 JavaMail
环境,
以便通过 Session 对象创建其他重要类的实例。
Transport 和 Store:传输和存储
邮 件 操 作 只 有 发 送 或 接 收 两 种 处 理 方 式 , JavaMail 将 这 两
种 不 同 操 作 描 述 为 传 输
(javax.mail.Transport) 和存储(javax.mail.Store) ,
传输对应邮件的发送, 而存储对应邮件
的接收。
Message:消息对象
一旦获得 Session 对象, 就可以继续创建要发送的消息。 这由 Message
类来完成。 因
为 Message 是个抽象类, 您必需用一个子类, 多数情况下为
javax.mail.internet.MimeMessage。
MimeMessage 是个能理解 MIME 类型和头的电子邮件消息, 正如不同 RFC
中所定义的。 虽
然在某些头部域非 ASCII 字符也能被译码, 但 Message 头只能被限制为用
US-ASCII 字符。
Address:地址
一旦您创建了 Session 和 Message, 并将内容填入消息后, 就可以用 Address

定信件地址了。 和 Message 一样, Address 也是个抽象类。 您用的
是 javax.mail.internet.InternetAddress 类。
若创建的地址只包含电子邮件地址, 只要传递电子邮件地址到构造器就行了。
Authenticator:认证者
与 java 类一样, JavaMail API 也可以利用 Authenticator
通过用户名和密码访
问受保护的资源。 对于 JavaMail API 来说, 这些资源就是邮件服务器。
JavaMail
Authenticator 在 javax.mail 包中, 而且它和 java.net 中同名的类
Authenticator 不
同。 两者并不共享同一个 Authenticator, 因为 JavaMail API 用于 Java
1.1, 它没
有 java.net 类别。 要使用 Authenticator, 先创建一个抽象类的子类, 并
从 getPasswordAuthentication() 方法中返回 PasswordAuthentication 实例。
创建完
成后, 您必需向 session 注册 Authenticator。 然后, 在需要认证的时候,
就会通
知 Authenticator。 您可以弹出窗口,
也可以从配置文件中(虽然没有加密是不安
全的) 读取用户名和密码, 将它们作为 PasswordAuthentication
对象返回给调用
程序。

[6.4、 Java mail 发送邮件 环境准备]{.smallcaps}
1.jar 下载

通过 java mail 发送邮件, 首先需要下载对应 Java mail jar 包 下载地址:
http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-eeplat-419426.html#javamail-1.4.5-oth-JPR

2.个人邮箱准备这里以(163 邮箱为例)
注册 163 邮箱, 登录 163 邮箱后 设置邮箱账户开通 smtp 协议

image.png

登录到邮箱后 获取邮箱客户端授权码这里需要根据注册时输入的手机后输入 163
服务器发送的验证码来开通, 开通成功
记住个人授权访问码会以短信通知到对应手机, 该授权码是后面通过 Java mail
发送邮件的认证密码 非常重要 不要记错.

image.png

6.5、 Java mail 邮件发送实现

image.png

1.发送普通文本邮件

1)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>com.shsxt</groupId>
  <artifactId>spring07-email</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>spring07-email</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <!-- 添加JavaMail依赖 -->
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4</version>
    </dependency>

    <!-- spring 核心jar 依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <!-- spring 上下文环境 支持 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>


  </dependencies>

  <build>

  </build>
</project>


2)创建认证类MyAtuhenticator继承Authenticator

public class MyAuthenticator extends Authenticator {
    private  String  username;
    private  String password;

    public MyAuthenticator(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username,password);
    }
}


3)创建发送类SendMail.java

public class SendMail {
    public void  send01() throws MessagingException {
        //1.設置邮件服务器参数
        //定义邮箱服务器配置
        Properties props =new Properties();
        //163邮件服务器地址
        props.put("mail.smtp.host","smtp.163.com");
        // 163 邮件服务器端口
        props.put("mail.smtp.port", "25");
        // 163 邮件服务器认证属性
        props.put("mail.smtp.auth", "true");

        //2创建session
        Session session =Session.getInstance(props,
                new MyAuthenticator("13255123823@163.com","why111"));

        //3.定义消息
        Message message =new MimeMessage(session);
        //设置发件人和收件人
        message.setFrom(new InternetAddress("13255123823@163.com"));
        message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
         message.setSentDate(new Date());//发送日期
        message.setSubject("第一封邮件"); //发送主题
        message.setText("hello, 欢迎你的回复!"); //发送内容

        //4.发送
        Transport.send(message);

    }


4)创建单元测试类SendMailTest类发送邮件

public class SendMailTest {
    @Test
    public void  send01() throws MessagingException {

        new SendMail().send01();
        System.out.println("发送了一封邮件");

    }


执行测试 发送成功 后 进入邮箱查看邮件 .

image.png

2.发送 html 邮件内容和发送带附件的内容

1)sendMail类中添加新的方法

/**
     * 发送html邮件
     * @throws MessagingException
     */
    public void  send02() throws MessagingException {
        //1.設置邮件服务器参数
        //定义邮箱服务器配置
        Properties props =new Properties();
        //163邮件服务器地址
        props.put("mail.smtp.host","smtp.163.com");
        // 163 邮件服务器端口
        props.put("mail.smtp.port", "25");
        // 163 邮件服务器认证属性
        props.put("mail.smtp.auth", "true");

        //2创建session
        Session session =Session.getInstance(props,
                new MyAuthenticator("13255123823@163.com","why111"));

        //3.定义消息
        Message message =new MimeMessage(session);
        //设置发件人和收件人
        message.setFrom(new InternetAddress("13255123823@163.com"));
        message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
         message.setSentDate(new Date());//发送日期
        message.setSubject("html邮件"); //发送主题
       //html邮件
        MimeMultipart multipart =new MimeMultipart();
        MimeBodyPart bodyPart =new MimeBodyPart();

        bodyPart.setContent(
                "<html><body><a href='http://www.baidu.com'>百度一下</a></body></html>",
                "text/html;charset=utf-8");
        multipart.addBodyPart(bodyPart);
        message.setContent(multipart);

        //4.发送
        Transport.send(message);

    }

    /**
     * 发送附件邮件
     * @throws MessagingException
     */
    public void  send03() throws MessagingException, UnsupportedEncodingException {
        //1.設置邮件服务器参数
        //定义邮箱服务器配置
        Properties props =new Properties();
        //163邮件服务器地址
        props.put("mail.smtp.host","smtp.163.com");
        // 163 邮件服务器端口
        props.put("mail.smtp.port", "25");
        // 163 邮件服务器认证属性
        props.put("mail.smtp.auth", "true");

        //2创建session
        Session session =Session.getInstance(props,
                new MyAuthenticator("13255123823@163.com","why111"));

        //3.定义消息
        Message message =new MimeMessage(session);
        //设置发件人和收件人
        message.setFrom(new InternetAddress("13255123823@163.com"));
        message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
         message.setSentDate(new Date());//发送日期
        message.setSubject("带附件邮件"); //发送主题
       //html邮件
        MimeMultipart multipart =new MimeMultipart();
        MimeBodyPart bodyPart =new MimeBodyPart();

        bodyPart.setContent(
                "<html><body><a href='http://www.baidu.com'>百度一下</a></body></html>",
                "text/html;charset=utf-8");
        multipart.addBodyPart(bodyPart);

        /*
        防附件
         */
        MimeBodyPart bodyPart02 =new MimeBodyPart();
        FileDataSource fds =new FileDataSource(new File("E:\\课程资料\\G04-spring02-7.5.2019\\practice\\spring07email\\pom.xml"));
       //设置附件
        bodyPart02.setDataHandler(new DataHandler(fds));
        //设置文件名
        bodyPart02.setFileName(MimeUtility.encodeText("pom.xml"));
       multipart.addBodyPart(bodyPart02);

       //加入一张图片
        MimeBodyPart bodyPart3 =new MimeBodyPart();
        FileDataSource fds2 =new FileDataSource(new File("C:\\Users\\Administrator\\Pictures\\11.jpg"));
       //设置附件
        bodyPart3.setDataHandler(new DataHandler(fds2));
       //设置文件名
        bodyPart3.setFileName(MimeUtility.encodeText("11.jpg"));
        multipart.addBodyPart(bodyPart3);
        message.setContent(multipart);

        //4.发送
        Transport.send(message);

    }
}


2)SendMailTest类发送html邮件

public class SendMailTest {
    @Test
    public void  send01() throws MessagingException {

        new SendMail().send01();
        System.out.println("发送了一封邮件");

    }
    @Test
    public void  send02() throws MessagingException {

        new SendMail().send02();
        System.out.println("发送了html邮件");

    }
    @Test
    public void  send03() throws  Exception {

        new SendMail().send03();
        System.out.println("发送了附件邮件");

    }



测试结果

image.png

3Java mail 邮件发送封装\

1)邮件发送器方法封装util包下建ShSxtMailSender

 package com.shsxt.util;

import com.shsxt.MyAuthenticator;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 简单封装邮件发送器 发送邮件实现
 * @author lp
 *
 */
public class ShSxtMailSender {

    public void sendHtmlMail(ShSxtMailSendInfo mailSendInfo){
        Message message=null;
        Session session=null;
        try {
            MyAuthenticator au=new MyAuthenticator(mailSendInfo.getUserName(), mailSendInfo.getUserPwd());

            Properties props=new Properties();
            // 163 邮件服务器地址
            props.put("mail.smtp.host", mailSendInfo.getServerHost());
            // 163 邮件服务器端口
            props.put("mail.smtp.port",mailSendInfo.getServerPort());
            // 163 邮件服务器认证属性 
            props.put("mail.smtp.auth", mailSendInfo.getFlag());


            session=Session.getDefaultInstance(props, au);

            message=new MimeMessage(session);
            Address from=new InternetAddress(mailSendInfo.getFromAddress());
            message.setFrom(from);
            message.setSentDate(new Date());
            if(null!=mailSendInfo.getToAddress()&&mailSendInfo.getToAddress().size()>0){
                Address[] addresses=new Address[mailSendInfo.getToAddress().size()];


                for(int i=0;i<mailSendInfo.getToAddress().size();i++){
                    Address address=new InternetAddress(mailSendInfo.getToAddress().get(i));
                    addresses[i]=address;
                }


                message.setRecipients(Message.RecipientType.TO, addresses);// 设置接收人地址
                message.setSubject(mailSendInfo.getSubject());
                Multipart multipart=new MimeMultipart();
                BodyPart bodyPart=new MimeBodyPart();
                bodyPart.setContent(mailSendInfo.getContent(), "text/html;charset=utf-8");
                multipart.addBodyPart(bodyPart);
                // 附件添加
                List<String> files=mailSendInfo.getAttachFileNames();
                if(null!=files&&files.size()>0){


                    for(int i=0;i<files.size();i++){
                        File tempFile=new File(files.get(i));
                        if(tempFile.exists()){
                            BodyPart temp=new MimeBodyPart();
                            temp.setDataHandler(new DataHandler(new FileDataSource(tempFile)));
                            temp.setFileName(MimeUtility.encodeText (tempFile.getName()));//设置文件名
                            multipart.addBodyPart(temp);//添加附件
                        }
                    }


                }
                // 设置邮件内容
                message.setContent(multipart);  
                Transport.send(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


2)邮件发送信息类简单封装ShSxtMailSendInfo

package com.shsxt.util;

import java.util.List;

/**
 * 邮件发送信息类
 *   定义发送邮件时 邮件服务器  端口 发送方用户名 密码等字段
 * @author lp
 *
 */
public class ShSxtMailSendInfo {
    
    private String serverHost;// 服务器主机
    private String serverPort;//服务器端口
    private String fromAddress;//发送方邮箱地址
    private List<String> toAddress;// 接收方邮箱地址
    
    private String userName;//邮件服务器用户名
    private String userPwd;//邮件服务器密码
    
    private String subject;//邮件主题
    private String content;// 邮件内容
    
    
    private String flag="true";
    
    private List<String> attachFileNames;//附件文件名

    public String getFlag() {
        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }

    public String getServerHost() {
        return serverHost;
    }

    public void setServerHost(String serverHost) {
        this.serverHost = serverHost;
    }

    public String getServerPort() {
        return serverPort;
    }

    public void setServerPort(String serverPort) {
        this.serverPort = serverPort;
    }

    public String getFromAddress() {
        return fromAddress;
    }

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

    public List<String> getToAddress() {
        return toAddress;
    }

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

    public String getUserName() {
        return userName;
    }

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

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }

    public String getSubject() {
        return subject;
    }

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

    public String getContent() {
        return content;
    }

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

    public List<String> getAttachFileNames() {
        return attachFileNames;
    }

    public void setAttachFileNames(List<String> attachFileNames) {
        this.attachFileNames = attachFileNames;
    }
}


3)测试SendMailTest类发送 html和附件邮件

/**
 * 邮件发送封装
 */
@Test
public void testMail01() {
    ShSxtMailSendInfo shSxtMailSendInfo=new ShSxtMailSendInfo();
    shSxtMailSendInfo.setServerHost("smtp.163.com");
    shSxtMailSendInfo.setServerPort("25");
    shSxtMailSendInfo.setUserName("shsxt_test01@163.com");
    shSxtMailSendInfo.setUserPwd("shsxt123");
    shSxtMailSendInfo.setSubject("shsxt全体邮件");
    shSxtMailSendInfo.setFromAddress("shsxt_test01@163.com");
    shSxtMailSendInfo.setContent("hello shsxt");


    List<String> users=new ArrayList<String>();
    users.add("shsxt_test01@163.com");
    shSxtMailSendInfo.setToAddress(users);


    ShSxtMailSender mailSender=new ShSxtMailSender();
    mailSender.sendHtmlMail(shSxtMailSendInfo);
}

/**
 * 封装后发送带附件邮件测试
 */

@Test
public void testMail02() {
    ShSxtMailSendInfo shSxtMailSendInfo=new ShSxtMailSendInfo();
    shSxtMailSendInfo.setServerHost("smtp.163.com");
    shSxtMailSendInfo.setServerPort("25");
    shSxtMailSendInfo.setUserName("shsxt_test01@163.com");
    shSxtMailSendInfo.setUserPwd("shsxt123");
    shSxtMailSendInfo.setSubject("shsxt全体邮件");
    shSxtMailSendInfo.setFromAddress("shsxt_test01@163.com");
    shSxtMailSendInfo.setContent("hello shsxt");


    List<String> users=new ArrayList<String>();
    users.add("shsxt_test01@163.com");
    shSxtMailSendInfo.setToAddress(users);
    // 添加附件
    List<String> files=new ArrayList<String>();
    files.add("E:\\java_28\\spring07mail\\28期.bmp");
    files.add("E:\\java_28\\spring07mail\\pom.xml");
    shSxtMailSendInfo.setAttachFileNames(files);
    ShSxtMailSender mailSender=new ShSxtMailSender();
    mailSender.sendHtmlMail(shSxtMailSendInfo);
}


七、 使用 Spring api 实现邮件发送
1.环境准备
这里建立 maven 普通工程

image.png

添加坐标依赖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>com.shsxt</groupId>
  <artifactId>spring07-mail</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>spring07-mail</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!-- 添加JavaMail依赖 -->
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4</version>
    </dependency>

    <!-- spring 核心jar 依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <!-- spring 上下文环境 支持 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
  </build>
</project>


2.配置文件配置邮件发送 bean
借助 spring 环境配置邮件发送相关 bean,spring.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 开启包扫描 -->
    <context:component-scan base-package="com.shsxt"/>

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.163.com" />
        <property name="port" value="25" />
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="username" value="shsxt_test01@163.com"></property>
        <property name="password" value="shsxt123"></property>
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">true</prop>
            </props>
        </property>
    </bean>
    <bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
        <property name="from" value="shsxt_test01@163.com" />
        <property name="subject" value="spring_mail" />
    </bean>
    <bean id="orderManager" class="com.shsxt.spring.SimpleOrderManager">
        <property name="mailSender" ref="mailSender" />
        <property name="templateMessage" ref="templateMessage" />
    </bean>

    <!-- 配置定时任务 -->
    <!-- 通过注解 -->
    <!-- 开启定时任务注解 -->
    <task:annotation-driven />
    <bean id="myJob02" class="com.shsxt.task.MyJob02"></bean>
</beans>


3.发送接口定义与实现

package-orderManger接口

/**
 * 发送邮件接口定义
 * @author lp
 *
 */
public interface OrderManager {
    void placeOrder();
}


package-SimpleorderManger实现类

**
 * 接口实现类
 */
public class SimpleOrderManager implements OrderManager {

    private MailSender mailSender;
    private SimpleMailMessage templateMessage;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setTemplateMessage(SimpleMailMessage templateMessage) {
        this.templateMessage = templateMessage;
    }

    @Override
    public void placeOrder() {

        SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);


        msg.setTo("shsxt_test01@163.com");
        msg.setText("test...asdasdasdsd");


        try {
            this.mailSender.send(msg);
        } catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }


    public void sendFileMail() throws MessagingException {
        JavaMailSender mailSender2= (JavaMailSender) mailSender;
        MimeMessage message= mailSender2.createMimeMessage();
        message.setSubject("spring_mail");
        // 创建带有附件的消息帮组类
        MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
        helper.setTo(new InternetAddress("shsxt_test01@163.com"));//设置接收人
        helper.setText("Thank you for ordering!");
        helper.setFrom("shsxt_test01@163.com");
        helper.addAttachment("28期.bmp", new File("E:\\java_28\\spring08-mail\\28期.bmp"));
        mailSender2.send(message);
    }

}


4.测试效果SimpleOrderMangerTest

public class SimpleOrderManagerTest {
    @Test
    public void placeOrder() throws Exception {

        ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
        OrderManager orderManager= (OrderManager) ac.getBean("orderManager");
        orderManager.placeOrder();

    }

    /**
     * 发送附件spring-mail
     * @throws Exception
     */
    @Test
    public void placeOrder02() throws Exception {

        ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
        JavaMailSender mailSender= (JavaMailSender) ac.getBean("mailSender");

        MimeMessage message= mailSender.createMimeMessage();
        message.setSubject("spring_mail_file");
        // 创建带有附件的消息帮组类
        MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
        helper.setTo(new InternetAddress("shsxt_test01@163.com"));//设置接收人
        helper.setText("Thank you for ordering!");
        helper.setFrom("shsxt_test01@163.com");

        helper.addAttachment("pom.xml", new File("E:\\java_28\\spring07mail\\pom.xml"));

        mailSender.send(message);

    }

}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容