Servlet

  • 1.Servlet 技术
    • a)什么是 Servlet
    • b)手动实现 Servlet 程序
    • c)url 地址到 Servlet 程序的访问
    • d)Servlet 的生命周期
    • e)GET 和 POST 请求的分发处理
    • f)通过继承 HttpServlet 实现 Servlet 程序
    • g)使用 IDEA 创建 Servlet 程序
    • h)Servlet 类的继承体系
  • 2.ServletConfig 类
    • a)ServletConfig 类的三大作用
  • 3.ServletContext 类
    • a)什么是 ServletContext?
    • b)ServletContext 类的四个作用
  • 4.HTTP 协议
    • a)什么是 HTTP 协议
    • b)请求的 HTTP 协议格式
      • i.GET 请求
      • ii.POST 请求
      • iii.常用请求头的说明
      • iv.哪些是GET 请求,哪些是 POST 请求
    • c)响应的 HTTP 协议格式
    • d)常用的响应码说明
    • e)MIME 类型说明
  • 5.HttpServletRequest 类
    • a)HttpServletRequest 类有什么作用。
    • b)HttpServletRequest 类的常用方法
    • c)如何获取请求参数
    • d)POST 请求的中文乱码解决
    • e)请求的转发
    • f)base 标签的作用
    • g)Web 中的相对路径和绝对路径
    • h)web 中 / 斜杠的不同意义
  • 6.HttpServletResponse 类
    • a)HttpServletResponse 类的作用
    • b)两个输出流的说明。
    • c)如何往客户端回传数据
    • d)响应的乱码解决
    • e)请求重定向
  • 7. 文件的下载
  • 8. 验证码功能
  • 9. 文件的上传
  • 10. 邮件发送
    • 1. 传输协议
    • 2. 邮件收发原理
    • 3. Java发送邮件
      • 1. 纯文本邮件
      • 2. 带图片和附件的邮件
        • 1 创建包含内嵌图片的邮件
        • 2 带图片和附件的复杂邮件发送
    • 4. JavaWeb发送邮件

1.Servlet 技术

a)什么是 Servlet

1、Servlet 是 JavaEE 规范之一。规范就是接口
2、Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
3、Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

b)手动实现 Servlet 程序

1、编写一个类去实现 Servlet 接口
2、实现 service 方法,处理请求,并响应数据
3、到 web.xml 中去配置 servlet 程序的访问地址

Servlet 程序的示例代码:

web.xml 中的配置:

常见的错误 1:url-pattern 中配置的路径没有以斜杠打头。

常见错误 2:servlet-name 配置的值不存在:

常见错误 3:servlet-class 标签的全类名配置错误:

c)url 地址到 Servlet 程序的访问

d)Servlet 的生命周期

1、执行 Servlet 构造器方法
2、执行 init 初始化方法

第一、二步,是在第一次访问,的时候创建 Servlet 程序会调用。

3、执行 service 方法

第三步,每次访问都会调用。

4、执行 destroy 销毁方法

第四步,在 web 工程停止的时候调用。

e)GET 和 POST 请求的分发处理

public class HelloServlet implements Servlet {/**
*service 方法是专门用来处理请求和响应的
*@param servletRequest
*@param servletResponse
*@throws ServletException
*@throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws
ServletException, IOException {
System.out.println("3 service === Hello Servlet 被访问了");
// 类型转换(因为它有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取请求的方式
String method = httpServletRequest.getMethod();if ("GET".equals(method)) { doGet();
} else if ("POST".equals(method)) {
doPost();
}}/**
*做get 请求的操作
*/
public void doGet(){ System.out.println("get 请求");
System.out.println("get 请求");
}
/**
*做post 请求的操作
*/
public void doPost(){ System.out.println("post 请求");
System.out.println("post 请求");
}}

f)通过继承 HttpServlet 实现 Servlet 程序

一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。

1、编写一个类去继承 HttpServlet 类
2、根据业务需要重写 doGet 或 doPost 方法
3、到 web.xml 中的配置 Servlet 程序的访问地址

Servlet 类的代码:

web.xml 中的配置:

g)使用 IDEA 创建 Servlet 程序

菜单:new ->Servlet 程序

配置 Servlet 的信息:

h)Servlet 类的继承体系

2.ServletConfig 类

ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。
Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。
Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象。

a)ServletConfig 类的三大作用

1、可以获取 Servlet 程序的别名 servlet-name 的值
2、获取初始化参数 init-param
3、获取 ServletContext 对象

web.xml 中的配置:


Servlet 中的代码:

注意点:

3.ServletContext 类

a)什么是 ServletContext?

1、ServletContext 是一个接口,它表示 Servlet 上下文对象
2、一个 web 工程,只有一个 ServletContext 对象实例。
3、ServletContext 对象是一个域对象。
4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。

什么是域对象?

域对象,是可以像 Map 一样存取数据的对象,叫域对象。这里的域指的是存取数据的操作范围,整个 web 工程。

                 存数据         取数据         删除数据
Map             put()           get()           remove()
域对象     setAttribute()  getAttribute()  removeAttribute();

b)ServletContext 类的四个作用

1、获取 web.xml 中配置的上下文参数 context-param 2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像 Map 一样存取数据

ServletContext 演示代码:

web.xml 中的配置:

ServletContext 像 Map 一样存取数据:

ContextServlet1 代码:

ContextServlet2 代码:


4.HTTP 协议

a)什么是 HTTP 协议

什么是协议?

协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。

所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。

HTTP 协议中的数据又叫报文。

b)请求的 HTTP 协议格式

客户端给服务器发送数据叫请求。服务器给客户端回传数据叫响应。

请求又分为 GET 请求,和 POST 请求两种

i.GET 请求

1、请求行

(1)请求的方式 GET
(2)请求的资源路径[+?+请求参数]
(3)请求的协议的版本号 HTTP/1.1 2、请求头
key : value 组成 不同的键值对,表示不同的含义。

ii.POST 请求

1、请求行

(1)请求的方式 POST
(2)请求的资源路径[+?+请求参数]
(3)请求的协议的版本号 HTTP/1.1

2、请求头

  1. key : value 不同的请求头,有不同的含义

空行

3、请求体 ===>>> 就是发送给服务器的数据

iii.常用请求头的说明

Accept: 表示客户端可以接收的数据类型
Accpet-Languege: 表示客户端可以接收的语言类型
User-Agent: 表示客户端浏览器的信息
Host: 表示请求时的服务器 ip 和端口号

iv.哪些是GET 请求,哪些是 POST 请求

GET 请求有哪些:

1、form 标签 method=get 2、a 标签
3、link 标签引入 css
4、Script 标签引入 js 文件
5、img 标签引入图片
6、iframe 引入 html 页面
7、在浏览器地址栏中输入地址后敲回车

POST 请求有哪些:

8、form 标签 method=post

c)响应的 HTTP 协议格式

1、响应行

(1)响应的协议和版本号
(2)响应状态码
(3)响应状态描述符

2、响应头

(1) key : value 不同的响应头,有其不同含义空行

3、响应体 ---->>> 就是回传给客户端的数据

d)常用的响应码说明

200 表示请求成功
302 表示请求重定向(明天讲)
404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
500 表示服务器已经收到请求,但是服务器内部错误(代码错误)

e)MIME 类型说明

MIME 是 HTTP 协议中数据类型。
MIME 的英文全称是"Multipurpose Internet Mail Extensions" 多功能 Internet 邮件扩充服务。MIME 类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。

常见的 MIME 类型:


谷歌浏览器如何查看 HTTP 协议:

火狐浏览器如何查看 HTTP 协议:

5.HttpServletRequest 类

a)HttpServletRequest 类有什么作用。

每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。

b)HttpServletRequest 类的常用方法

i.getRequestURI() 获取请求的资源路径
ii.getRequestURL() 获取请求的统一资源定位符(绝对路径)
iii.getRemoteHost() 获取客户端的 ip 地址
iv.getHeader() 获取请求头
v.getParameter() 获取请求的参数
vi.getParameterValues() 获取请求的参数(多个值的时候使用)
vii.getMethod() 获取请求的方式GET 或POST
viii.setAttribute(key, value); 设置域数据
ix.getAttribute(key); 获取域数据
x.getRequestDispatcher() 获取请求转发对象

常用API 示例代码:


c)如何获取请求参数

表单:

Java 代码:

doGet 请求的中文乱码解决:

d)POST 请求的中文乱码解决

e)请求的转发

什么是请求的转发?

请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。

Servlet1 代码:


Servlet2 代码:

f)base 标签的作用


g)Web 中的相对路径和绝对路径

在 javaWeb 中,路径分为相对路径和绝对路径两种: 相对路径是:

. 表示当前目录
… 表示上一级目录
资源名 表示当前目录/资源名

绝对路径:

http://ip:port/工程路径/资源路径

在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。

1、绝对路径
2、base+相对

h)web 中 / 斜杠的不同意义

在 web 中 / 斜杠 是一种绝对路径。

/ 斜杠 如果被浏览器解析,得到的地址是:http://ip:port/

<a href="/">斜杠</a>

/ 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径

1、<url-pattern>/servlet1</url-pattern>
2、servletContext.getRealPath(“/”);
3、request.getRequestDispatcher(“/”)

特殊情况:

response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到 http://ip:port/

6.HttpServletResponse 类

a)HttpServletResponse 类的作用

HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,
我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置

b)两个输出流的说明。

字节流 getOutputStream(); 常用于下载(传递二进制数据)
字符流 getWriter(); 常用于回传字符串(常用)
两个流同时只能使用一个。
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。

c)如何往客户端回传数据

要求 : 往客户端回传 字符串 数据。

d)响应的乱码解决

解决响应中文乱码方案一(不推荐使用):

解决响应中文乱码方案二(推荐):

e)请求重定向

请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求 重定向(因为之前的地址可能已经被废弃)。

请求重定向的第一种方案:

// 设置响应状态码302 ,表示重定向,(已搬迁)
resp.setStatus(302);
// 设置响应头,说明 新的地址在哪里
resp.setHeader(“Location”, “http://localhost:8080”);

请求重定向的第二种方案(推荐使用):

resp.sendRedirect(“http://localhost:8080”);

7. 文件的下载

1 要获取下载文件的路径

2 下载的文件名是啥?

3 设置想办法让浏览器能够支持下载我们需要的东西

4 获取下载文件的输入流

5 创建缓冲区

6 获取OutputStream对象

7 将FileOutputStream流写入到bufer缓冲区

8 使用OutputStream将缓冲区中的数据输出到客户端!

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 要获取下载文件的路径String realPath = "F:\\2、代码\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\秦疆.png";System.out.println("下载文件的路径:"+realPath);// 2. 下载的文件名是啥?String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);// 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));// 4. 获取下载文件的输入流FileInputStream in = new FileInputStream(realPath);// 5. 创建缓冲区int len = 0;byte[] buffer = new byte[1024];// 6. 获取OutputStream对象ServletOutputStream out = resp.getOutputStream();// 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!while ((len=in.read(buffer))>0){out.write(buffer,0,len);}in.close();out.close();
}

8. 验证码功能

验证怎么来的?

前端实现

后端实现,需要用到Java的图片类,生产一个图片

package com.kuang.servlet;import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;public class ImageServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//如何让浏览器3秒自动刷新一次;resp.setHeader("refresh","3");//在内存中创建一个图片BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);//得到图片Graphics2D g = (Graphics2D) image.getGraphics(); //笔//设置图片的背景颜色g.setColor(Color.white);g.fillRect(0,0,80,20);//给图片写数据g.setColor(Color.BLUE);g.setFont(new Font(null,Font.BOLD,20));g.drawString(makeNum(),0,20);//告诉浏览器,这个请求用图片的方式打开resp.setContentType("image/jpeg");//网站存在缓存,不让浏览器缓存resp.setDateHeader("expires",-1);resp.setHeader("Cache-Control","no-cache");resp.setHeader("Pragma","no-cache");//把图片写给浏览器ImageIO.write(image,"jpg", resp.getOutputStream());}//生成随机数private String makeNum(){Random random = new Random();String num = random.nextInt(9999999) + "";StringBuffer sb = new StringBuffer();for (int i = 0; i < 7-num.length() ; i++) {sb.append("0");}num = sb.toString() + num;return num;}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
<servlet><servlet-name>ImageServlet</servlet-name><servlet-class>com.kuang.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>Imageservlet</servlet-name><url-pattern>/img</url-pattern>
</servlet-mapping>

9. 文件的上传

① 文件上传的注意事项

1.为保证服务器安全,上传文件应该放在外界无法直接访问的目录下, 比如放于WEB-INF目录下。

2.为防止文件覆盖的现象发生,要为上传文件产生一个唯一 的文件名,为避免同名图片的出现可以使用MD5加密还有uid,时间戳等等。

3.要限制上传文件的最大值。

4.可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

② 文件上传原理

1 所需jar包

 <!--文件上传,导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包;--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version></dependency>

2 index.jsp
加载服务器地址固定写法:"${pageContext.request.contextPath}/upload.do"

<html>
<body>
<form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post"><input type="file" name="file"/><input type="submit" value="upload"></form>
</body>
</html>

3 FileServlet

public class FileServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//判断上传的文件是普通表非还是带文件的表单if (!ServletFileUpload.isMultipartContent(request)) {return; //终止方法运行说明这是一个普远的表单,直接返回}//创建上:传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件;String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");File uploadFile = new File(uploadPath);if (!uploadFile.exists()) {uploadFile.mkdir(); //创建这个目录}//级存,临时文件//临时路径,假如文件超过J预期的大小,我们就把他放到一一个临时文件中,过几天自动删除,或者提醒用户转存为承久String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");File file = new File(tmpPath);if (!file.exists()) {file.mkdir(); //创建这个临时目录}//处理上传的文件,一般 都需要通过流来获取,我们可以使request. getInputstream(),原生态的文件上传流获取,十分麻烦//但是我们都建议使用Apache的文件上:传组件米实现,common-fileupload, 它需要依赖于commons-io组件:/*ServletFileUpload负责处理上传的文件数据并将表单中每个输入项封装成- - 个FileItem对象。在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象。所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象。通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。*/try {//1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;DiskFileItemFactory factory = getDiskFileItemFactory(file);//2.获取ServletFileUploadServletFileUpload upload = getServletFileUpload(factory);//3.处理上传的文件String msg = uploadParseRequest(upload, request, uploadPath);//servlet请求转发消息request.setAttribute("msg", msg);request.getRequestDispatcher("info.jsp").forward(request, response);} catch (FileUploadException e) {e.printStackTrace();}}public static DiskFileItemFactory getDiskFileItemFactory(File file) {DiskFileItemFactory factory = new DiskFileItemFactory();//通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中;factory.setSizeThreshold(1024 * 1024); //缓存区大小为1Mfactory.setRepository(file);//临时目录的保存目录,需要一个Filereturn factory;}public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {ServletFileUpload upload = new ServletFileUpload(factory);//监听文件上传进度;upload.setProgressListener(new ProgressListener() {@Override//pBytesRead:已经读取到的文件大小//pContentlength :文件大小public void update(long pBytesRead, long pContentLength, int pItems) {System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead);}});//处理乱码问题upload.setHeaderEncoding("UTF-8");//设置单个文件的最大值upload.setFileSizeMax(1024 * 1024 * 10);//设置总共能够上传文件的大小//1024=1kb*1024=1M*10=10Mupload.setSizeMax(1024 * 1024 * 10);return upload;}public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath)throws FileUploadException, IOException {String msg = "";//3.把前端请求解析,封装成一个FileItem对象List<FileItem> fileItems = upload.parseRequest(request);for (FileItem fileItem : fileItems) {if (fileItem.isFormField()) { //判断上传的文件是普通的表单还是带文件的表单//getFieldName指的是前端表单控件的name;String name = fileItem.getFieldName();String value = fileItem.getString("UTF-8"); //处理乱码System.out.println(name + ":" + value);} else { //判断它是上传的文件/*====================处理文件========================*///拿到文件名字String uploadFileName = fileItem.getName();System.out.println("上传的文件名: " + uploadFileName);if (uploadFileName.trim().equals("") || uploadFileName == null) {continue;}//获得上传的文件名/images/girl/paojie. pngString fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);//获得文件的后缀名String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);/*如果文件后缀名fileExtName 不是我们所需要的就直接return,不处理,告诉用户文件类型不对。*/System.out.println("文件信息[件名: " + fileName + "---文件类型" + fileExtName + "]");//可以使用UUID (唯一识别的通用码),保证文件名唯一;//UUID. randomUUID(),随机生一个唯一识别的通 用码;String uuidPath = UUID.randomUUID().toString();/*==================处理文件完-=======================*///存到哪? uploadPath//文件真实存在的路径realPathString realPath = uploadPath + "/" + uuidPath;//给每个文件创建一个对应的文件夹File realPathFile = new File(realPath);if (!realPathFile.exists()) {realPathFile.mkdir();}/*====================存放地址完毕-========================*///获得文件上传的流InputStream inputStream = fileItem.getInputStream();//创建一个文件输出流//realPath =真实的文件夹;//差了一个文件;加上输出文件的名字+"/"+uuidFileNameFileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);//创建一个缓冲区byte[] buffer = new byte[1024 * 1024];//判断是否读取完毕int len = 0;//如果大于0说明还存在数据;while ((len = inputStream.read(buffer)) > 0) {fos.write(buffer, 0, len);}//关闭流fos.close();inputStream.close();msg = "文件上传成功!";fileItem.delete(); //上传成功,清除临时文件/*====================文件传输完==========================*/}}return msg;}
}

4 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"><servlet><servlet-name>FileServlet</servlet-name><servlet-class>com.lenovo.servlet.FileServlet</servlet-class></servlet><servlet-mapping><servlet-name>FileServlet</servlet-name><url-pattern>/upload.do</url-pattern></servlet-mapping></web-app>

5 info.xml

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
${msg}
</body>
</html>

6 将文件从本地传至服务器

注意:上面的目录只是我们编写代码的文件目录,而我们点击项目发布之后,IDEA会产生一个target文件夹

10. 邮件发送

1. 传输协议

SMTP协议

发送邮件:我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。

POP3协议

接收邮件:我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。

2. 邮件收发原理

1首先通过smtp协议连接到Smtp服务器,然后发送一封邮件给网易的邮件服务器

2网易分析发现需要去QQ的邮件服务器,通过smtp协议将邮件转投给QQ的Smtp服务器

3QQ将接收到的邮件存储在xxx@qq.com这个邮件账号的空间中

4再通过Pop3协议连接到Pop3服务器收取邮件

5从xxx@qq.com这个邮件账号的空间中取出邮件

6Pop3服务器将取出来的邮件送出去

【注意】有可能填写的收件人地址,发件人地址等信息都正确了,控制台也打印了正确的信息,但是在收件箱就是收不到信息。这是因为可能收件箱服务器拒收了你发的邮件(比如认为你的邮件是广告),这时候可能在垃圾箱里能找到,可能找不到。解决办法是重复的邮件内容不要多次发送,或者更换收件箱试试

3. Java发送邮件

概述

我们将用代码完成邮件的发送。这在实际项目中应用的非常广泛,比如注册需要发送邮件进行账号激活,再比如OA项目中利用邮件进行任务提醒等等。

使用Java发送 E-mail 十分简单,但是首先你应该准备 JavaMail API 和Java Activation Framework 。

得到两个jar包:

  • mail.jar
  • activation.jar

JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等。我们在使用JavaMail API 编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail 开发包中相应的API类就可以了。

我们可以先尝试发送一封简单的邮件,首先请确保电脑可以连接网络。

  • 创建包含邮件服务器的网络连接信息的Session对象。
  • 创建代表邮件内容的Message对象
  • 创建Transport对象,连接服务器,发送Message,关闭连接

主要有四个核心类,我们在编写程序时,记住这四个核心类,就很容易编写出Java邮件处理程序,如图所示:

1. 纯文本邮件

先在项目中导入jar包

导入的就是在概述中提到的activation,jar和mail.jar包,如图所示:

QQ邮箱中获取对应的权限

QQ邮箱需要安全验证,我们需要获取他对应的权限;

进入QQ邮箱–>邮箱设置–>账户,下滑找到POP3/IMAP/SMTP/Exchange/CardDav/CalDav服务,开启POP3/SMTP服务,如图所示:



记住这16位授权码,然后开始编写测试程序:

public class SendEmail {public static void main(String[] args) throws Exception {Properties prop = new Properties();prop.setProperty("mail.host", "smtp.qq.com");  设置QQ邮件服务器prop.setProperty("mail.transport.protocol", "smtp"); // 邮件发送协议prop.setProperty("mail.smtp.auth", "true"); // 需要验证用户名密码// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);prop.put("mail.smtp.ssl.enable", "true");prop.put("mail.smtp.ssl.socketFactory", sf);//使用JavaMail发送邮件的5个步骤//创建定义整个应用程序所需的环境信息的 Session 对象Session session = Session.getDefaultInstance(prop, new Authenticator() {public PasswordAuthentication getPasswordAuthentication() {//发件人邮件用户名、授权码return new PasswordAuthentication("545646733@qq.com", "授权码");}});//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态session.setDebug(true);//2、通过session得到transport对象Transport ts = session.getTransport();//3、使用邮箱的用户名和授权码连上邮件服务器ts.connect("smtp.qq.com", "545646733@qq.com", "授权码");//4、创建邮件//创建邮件对象MimeMessage message = new MimeMessage(session);//指明邮件的发件人message.setFrom(new InternetAddress("545646733@qq.com"));//指明邮件的收件人,现在发件人和收件人是一样的,那就是自己给自己发message.setRecipient(Message.RecipientType.TO, new InternetAddress("545646733@qq.com"));//邮件的标题message.setSubject("只包含文本的简单邮件");//邮件的文本内容message.setContent("你好啊!", "text/html;charset=UTF-8");//5、发送邮件ts.sendMessage(message, message.getAllRecipients());ts.close();}}

2. 带图片和附件的邮件

先认识两个类一个名词:

MIME(多用途互联网邮件扩展类型)

MimeBodyPart类

javax.mail.internet.MimeBodyPart类 表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。

MimeMultipart类

javax.mail.internet.MimeMultipart是抽象类 Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。

1 创建包含内嵌图片的邮件

前面的例子中是单独的使用HTML或者是纯文本内容,但是有时候我们需要在纯文本中使用内嵌的方式显示一些图片,因此就要将纯文本和内嵌图片单独存放在MimeBodyPart中然后再将其存放在一个Mimemultipart对象中即可。

代码如下:

public class SendImageEmail {public static void main(String[] args) throws Exception {Properties prop = new Properties();prop.setProperty("mail.host", "smtp.qq.com");  设置QQ邮件服务器prop.setProperty("mail.transport.protocol", "smtp"); // 邮件发送协议prop.setProperty("mail.smtp.auth", "true"); // 需要验证用户名密码// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);prop.put("mail.smtp.ssl.enable", "true");prop.put("mail.smtp.ssl.socketFactory", sf);//使用JavaMail发送邮件的5个步骤//1、创建定义整个应用程序所需的环境信息的 Session 对象Session session = Session.getDefaultInstance(prop, new Authenticator() {public PasswordAuthentication getPasswordAuthentication() {//发件人邮件用户名、授权码return new PasswordAuthentication("545646733@qq.com", "授权码");}});//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态session.setDebug(true);//2、通过session得到transport对象Transport ts = session.getTransport();//3、使用邮箱的用户名和授权码连上邮件服务器ts.connect("smtp.qq.com", "545646733@qq.com", "授权码");//4、创建邮件//创建邮件MimeMessage message = new MimeMessage(session);// 设置邮件的基本信息//发件人message.setFrom(new InternetAddress("545646733@qq.com"));//收件人message.setRecipient(Message.RecipientType.TO, new InternetAddress("545646733@qq.com"));//邮件标题message.setSubject("带图片的邮件");// 准备邮件数据// 准备图片数据MimeBodyPart image = new MimeBodyPart();DataHandler dh = new DataHandler(new FileDataSource("src/resources/bz.jpg"));image.setDataHandler(dh);image.setContentID("bz.jpg");// 准备正文数据MimeBodyPart text = new MimeBodyPart();text.setContent("这是一封邮件正文带图片<img src='cid:bz.jpg'>的邮件", "text/html;charset=UTF-8");// 描述数据关系MimeMultipart mm = new MimeMultipart();mm.addBodyPart(text);mm.addBodyPart(image);mm.setSubType("related");//设置到消息中,保存修改message.setContent(mm);message.saveChanges();//5.发送邮件ts.sendMessage(message, message.getAllRecipients());ts.close();}
}

2 带图片和附件的复杂邮件发送

代码如下:

public class SendFileMail {public static void main(String[] args) throws MessagingException, GeneralSecurityException {//创建一个配置文件保存并读取信息Properties properties = new Properties();//设置qq邮件服务器properties.setProperty("mail.host","smtp.qq.com");//设置发送的协议properties.setProperty("mail.transport.protocol","smtp");//设置用户是否需要验证properties.setProperty("mail.smtp.auth", "true");//=================================只有QQ存在的一个特性,需要建立一个安全的链接// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);properties.put("mail.smtp.ssl.enable", "true");properties.put("mail.smtp.ssl.socketFactory", sf);//=================================准备工作完毕//1.创建一个session会话对象;Session session = Session.getDefaultInstance(properties, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication("545646733@qq.com", "授权码");}});//可以通过session开启Dubug模式,查看所有的过程session.setDebug(true);//2.获取连接对象,通过session对象获得Transport,需要捕获或者抛出异常;Transport tp = session.getTransport();//3.连接服务器,需要抛出异常;tp.connect("smtp.qq.com","545646733@qq.com","授权码");//4.连接上之后我们需要发送邮件;MimeMessage mimeMessage = imageMail(session);//5.发送邮件tp.sendMessage(mimeMessage,mimeMessage.getAllRecipients());//6.关闭连接tp.close();}public static MimeMessage imageMail(Session session) throws MessagingException {//消息的固定信息MimeMessage mimeMessage = new MimeMessage(session);//邮件发送人mimeMessage.setFrom(new InternetAddress("545646733@qq.com"));//邮件接收人,可以同时发送给很多人,我们这里只发给自己;mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("545646733@qq.com"));mimeMessage.setSubject("我也不知道是个什么东西就发给你了"); //邮件主题/*编写邮件内容1.图片2.附件3.文本*///图片MimeBodyPart body1 = new MimeBodyPart();body1.setDataHandler(new DataHandler(new FileDataSource("src/resources/yhbxb.png")));body1.setContentID("yhbxb.png"); //图片设置ID//文本MimeBodyPart body2 = new MimeBodyPart();body2.setContent("请注意,我不是广告<img src='cid:yhbxb.png'>","text/html;charset=utf-8");//附件MimeBodyPart body3 = new MimeBodyPart();body3.setDataHandler(new DataHandler(new FileDataSource("src/resources/log4j.properties")));body3.setFileName("log4j.properties"); //附件设置名字MimeBodyPart body4 = new MimeBodyPart();body4.setDataHandler(new DataHandler(new FileDataSource("src/resources/1.txt")));body4.setFileName(""); //附件设置名字//拼装邮件正文内容MimeMultipart multipart1 = new MimeMultipart();multipart1.addBodyPart(body1);multipart1.addBodyPart(body2);multipart1.setSubType("related"); //1.文本和图片内嵌成功!//new MimeBodyPart().setContent(multipart1); //将拼装好的正文内容设置为主体MimeBodyPart contentText =  new MimeBodyPart();contentText.setContent(multipart1);//拼接附件MimeMultipart allFile =new MimeMultipart();allFile.addBodyPart(body3); //附件allFile.addBodyPart(body4); //附件allFile.addBodyPart(contentText);//正文allFile.setSubType("mixed"); //正文和附件都存在邮件中,所有类型设置为mixed;//放到Message消息中mimeMessage.setContent(allFile);mimeMessage.saveChanges();//保存修改return mimeMessage;}}

4. JavaWeb发送邮件

现在很多的网站都提供有用户注册功能, 通常我们注册成功之后就会收到一封来自注册网站的邮件。邮件里面的内容可能包含了我们的注册的用户名和密码以及一个激活账户的超链接等信息。今天我们也来实现一个这样的功能,用户注册成功之后,就将用户的注册信息以Email的形式发送到用户的注册邮箱当中,实现发送邮件功能就得借助于JavaMail了。

项目实现:

  1. 新建一个JavaWeb项目,配置tomcat的参数,然后添加jar包(记得在tomcat目录下的common目录下也导包,不然会报500错误),并且添加实体类User,Servlet类RegisterServlet,工具类Sendmail,如图所示:

    2.User类代码如下:
public class User {private String username;private String password;private String email;public User() {}public User(String username, String password, String email) {this.username = username;this.password = password;this.email = email;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +", email='" + email + '\'' +'}';}
}

3.前端注册页面register.jsp代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>注册</title>
</head>
<body><form action="${pageContext.request.contextPath}/RegisterServlet.do" method="post">用户名:<input type="text" name="username"><br/>密码:<input type="password" name="password"><br/>邮箱:<input type="text" name="email"><br/><input type="submit" value="注册">
</form></body>
</html>

4.工具类Sendmail类代码如下:

public class Sendmail extends Thread {//用于给用户发送邮件的邮箱private String from = "24736743@qq.com";//邮箱的用户名private String username = "24736743@qq.com";//邮箱的密码private String password = "授权码";//发送邮件的服务器地址private String host = "smtp.qq.com";private User user;public Sendmail(User user){this.user = user;}//重写run方法的实现,在run方法中发送邮件给指定的用户@Overridepublic void run() {try{Properties prop = new Properties();prop.setProperty("mail.host", host);prop.setProperty("mail.transport.protocol", "smtp");prop.setProperty("mail.smtp.auth", "true");// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);prop.put("mail.smtp.ssl.enable", "true");prop.put("mail.smtp.ssl.socketFactory", sf);//1、创建定义整个应用程序所需的环境信息的 Session 对象Session session = Session.getDefaultInstance(prop, new Authenticator() {public PasswordAuthentication getPasswordAuthentication() {//发件人邮件用户名、授权码return new PasswordAuthentication("24736743@qq.com", "授权码");}});//开启Session的debug模式,这样就可以查看到程序发送Email的运行状态session.setDebug(true);//2、通过session得到transport对象Transport ts = session.getTransport();//3、使用邮箱的用户名和授权码连上邮件服务器ts.connect(host, username, password);//4、创建邮件MimeMessage message = new MimeMessage(session);message.setFrom(new InternetAddress(from)); //发件人message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); //收件人message.setSubject("用户注册邮件"); //邮件的标题String info = "恭喜您注册成功,您的用户名:" + user.getUsername() + ",您的密码:" + user.getPassword() + ",请妥善保管,如有问题请联系网站客服!!";message.setContent(info, "text/html;charset=UTF-8");message.saveChanges();//发送邮件ts.sendMessage(message, message.getAllRecipients());ts.close();}catch (Exception e) {throw new RuntimeException(e);}}
}

5.Servlet类RegisterServlet类代码如下:

public class RegisterServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {//接收用户请求,封装成对象String username = request.getParameter("username");String password = request.getParameter("password");String email = request.getParameter("email");User user = new User(username,password,email);//用户注册成功之后,给用户发送一封邮件//我们使用线程来专门发送邮件,防止出现耗时,和网站注册人数过多的情况;Sendmail send = new Sendmail(user);//启动线程,线程启动之后就会执行run方法来发送邮件send.start();//注册用户request.setAttribute("message", "注册成功,我们已经发了一封带了注册信息的电子邮件,请查收!如网络不稳定,可能过会儿才能收到!!");request.getRequestDispatcher("info.jsp").forward(request, response);} catch (Exception e) {e.printStackTrace();request.setAttribute("message", "注册失败!!");request.getRequestDispatcher("info.jsp").forward(request, response);}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

6.配置web.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>register</servlet-name><servlet-class>com.kuang.servlet.RegisterServlet</servlet-class></servlet><servlet-mapping><servlet-name>register</servlet-name><url-pattern>/RegisterServlet.do</url-pattern></servlet-mapping>
</web-app>7.编写反馈页面info.jsp,代码如下:
```html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>提示信息</title>
</head>
<body>${message}
</body>
</html>

Servlet (Java Web 学习笔记)相关推荐

  1. java web学习笔记(持续更新)

    java web学习笔记 一.Java Web简介 二.认识Servlet 1.什么是Servlet? 2.请求路径 3.tomcat 4.Servlet的使用 三.Servlet简单应用 1.创建S ...

  2. 2019年Java Web学习笔记目录

    Java Web学习笔记目录 1.Java Web学习笔记01:动态网站初体验 2.Java Web学习笔记02:在Intellij里创建Web项目 3.Java Web学习笔记03:JSP元素 4. ...

  3. [原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)...

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. Java Web学习笔记 3 深入Servlet技术

    第3章 深入Servlet技术 请求-响应模式就是典型的Web应用程序访问过程,Java Web应用程序中,处理请求并发送响应的过程是由一种叫做Servlet的程序来完成的. 请求request,响应 ...

  5. [原创]java WEB学习笔记02:javaWeb开发的目录结构

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. [原创]java WEB学习笔记58:Struts2学习之路---Result 详解 type属性,通配符映射

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. 1、JAVA web学习笔记

    以下内容是在学习某机构视频过程中记录的笔记,不准确的地方请大家评论指正. JavaWeb是使用Java语言开发基于互联网的项目. 资源分类有两类: 静态资源: 使用静态网页开发技术发布的资源. 特点: ...

  8. [原创]java WEB学习笔记18:java EE 中的MVC 设计模式(理论)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  9. [原创]java WEB学习笔记35:java WEB 中关于绝对路径 和相对路径问题

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

最新文章

  1. 直方图均衡化opencv(彩色、灰度图)
  2. 蚂蚁金服开源增强版 Spring Boot 的研发框架!
  3. 一步步教你轻松学朴素贝叶斯模型算法理论篇1
  4. divmod数字处理函数
  5. AutoMapper在asp.netcore中的使用
  6. 水塔清洗机器人_最全的中央空调清洗流程
  7. oracle 设置输出显示中文乱码,修改oracle当前会话的语言环境,解决oracle显示中文乱码的问题 | 信春哥,系统稳,闭眼上线不回滚!...
  8. python random函数shuffle_Python|有趣的shuffle方法
  9. linux 多个文件中查找字符串
  10. 基于单片机的超市储物柜设计_毕业设计论-单片机储物柜
  11. Improving Opencv 5: The Core Functionality :Adding (blending) two images using OpenCV
  12. codeforces228A Is your horseshoe on the other hoof?(水题)
  13. java开发用win7好还是win10_win10和win7哪个好用|两个系统的性能比较
  14. Hive指定位置增加字段及解决columns have types incompatible with the existing columns in their respective positio
  15. Excel如何将汉字转成拼音
  16. 1008.判断闰年1.能被4整除而不能被100整除。(如2100年就不是闰年) 2.能被400整除。
  17. 关于Mariadb数据库 配置
  18. Word中删除全部页眉页脚的方法
  19. 比较两个数或者三个数的大小,输出较大数的值 Java
  20. 概念模型、数据模型、关系数据模型

热门文章

  1. [绍棠] 升级Xcode10和Xcode11问题集
  2. rust中文补丁steam_腐蚀rust游戏界面设置中文翻译图介文绍
  3. what is SEO ?
  4. Web版RSS阅读器yarr
  5. 人工神工机器人是什么_“神工二号”人工神经康复机器人 中国国产大白
  6. Android4.4KK中BOOT_COMPLETED广播问题的分析
  7. 第三方支付——快捷支付接口测试要点
  8. Java实现微信每天定时发送消息2.0 -- 柚子真好吃
  9. arduino 按钮读取_arduino Uno3中的按钮开关问题
  10. 应用逻辑(业务、商业逻辑)抽象出来