JavaWeb
- (二十五)、文件上传
- 1.准备工作
- 2.实用类介绍
- 3.思维导图:
- 4.正戏开始
- 5.完整代码
- (二十六)、邮箱发送
- 1.邮箱发送的原理:
- 2.服务器的原理
- 3.下载两个jar包
- 4.基本类:
- 5.全部代码
- (二十七)、网站注册发送邮件实现
- (二十八)、
(二十五)、文件上传
1.首先创建一个empty项目
2.配置project项目中的JDK
3.设置模板
4.添加web外部支持
5.基本思路
1.准备工作
下载两个jar包:
apache commons FileUpload
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
apache commons io
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
创建一个lib目录,然后把下载后的两个jar包放入到lib目录下,然后右键
点击 Add as library
点开项目结构,发现我们手动导入的lib目录不存在,所以要解决为问题
解决问题的存在
2.实用类介绍
文件上传的注意事项:
1.为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如
WEB-INF目录下
2.为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名(时间戳,uuid md5)
3.要限制上传文件的最大值 (比如朋友圈上传的视频,限制文件)
4.可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
需要用到的类详解:
ServletFileUpload负责处理上传的文件数据,并将表单中的每个输入项封装成一个Filetem对象,在使用ServletFileUpload对象解析请求时需要DiskFileletemFactory对象。所以,我们需要在进行解析工作前构造好DiskFileltemFactory对象,通过servletFileUpload对象的构造方法或setFileltemFactory()方法设置ServletFileUpload对象的FileitemFactory属性
3.思维导图:
4.正戏开始
(1).表单如果包含一个文件上传输入项的化,这个表单的enctype属性就必须设置为multipart/form-data
(2).在html页面input中必须有一个<input type="file" name="filename">
(3). get: 上传文件大小限制 post: 上传文件大无限制
1.创建文件目录
//* 判断文件上传的是普通表单还是带文件的表单,
if(ServletFileUpload.isMultipartContent(req)){
return;//如果是普通表带那就进入直接返回,否则就不运行
}try {
//创建上传文件的保存路径,建议保存为在web-inf的路径下,用户无法直接访问上面的图片
String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");
// 创建一个文件目录
File file = new File(realPath);
// 假如说文件目录不存在情况下,我们就创建
if(!file.exists()){
file.mkdir(); //创建这个目录
}
2.创建临时文件目录
//* 缓存,临时文件。假如文件超过了预期的大小,我们就把他放入到一个临时文件中,活几天自动删除或提示用户转存为永久
String tempRealPath = this.getServletContext().getRealPath("/WEB-INF/upload");
// 创建一个文件目录
File tempFile = new File(tempRealPath);
// 假如说文件目录不存在情况下,我们就创建
if(!tempFile.exists()){
tempFile.mkdir(); //创建这个临时目录
}
3.设置工厂
//* 处理上传的文件,一般都需要通过流来获取,我们可以使用req.getInputStream(),原生态的上传流获取,十分麻烦
// 但是我们都建议使用Apeache的文件上传组件来实现,common.fileupload,它需要依赖于commons-io组件
// ***************** 1.创建DiskFileItemFactory对象,处理文件上传路径或则大小限制的
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 2.通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将她放到临时文件中去
diskFileItemFactory.setSizeThreshold(1024*1024); //缓存大小为1MB
// 3.
diskFileItemFactory.setRepository(tempFile); //临时目录的保存目录,需要一个file
4.获取servletFileUpload
// ******************* 4.获取servletFileUpload
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
// 5.监听文件上传的速度
servletFileUpload.setProgressListener(new ProgressListener() {
public void update(long l, long l1, int i) {
System.out.println("总大小"+l1+"已上传:"+l);
}
});
// 处理乱码问题
servletFileUpload.setHeaderEncoding("UTF-8");
// 设置单个文件的最大值
// 1024=1kb*1024=1MB*10=10MB
servletFileUpload.setSizeMax(1024*1024*10);
implements sericlizable : 标记接口,JVM----》本地方法栈 native -->C++
5.完整代码
package com.Jsxs.Servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.junit.jupiter.api.Test;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
public class Servlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = "文件上传失败!";
//* 判断文件上传的是普通表单还是带文件的表单,
// if (ServletFileUpload.isMultipartContent(req)) {
// System.out.println("失败");
// return;//如果是普通表带那就进入直接返回,否则就不运行
// }
try {
//创建上传文件的保存路径,建议保存为在web-inf的路径下,用户无法直接访问上面的图片
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
// 创建一个文件目录
File file = new File(uploadPath);
// 假如说文件目录不存在情况下,我们就创建
if (!file.exists()) {
file.mkdir(); //创建这个目录
}
//* 缓存,临时文件。假如文件超过了预期的大小,我们就把他放入到一个临时文件中,活几天自动删除或提示用户转存为永久
String tempRealPath = this.getServletContext().getRealPath("/WEB-INF/upload");
// 创建一个文件目录
File tempFile = new File(tempRealPath);
// 假如说文件目录不存在情况下,我们就创建
if (!tempFile.exists()) {
tempFile.mkdir(); //创建这个临时目录
}
//* 处理上传的文件,一般都需要通过流来获取,我们可以使用req.getInputStream(),原生态的上传流获取,十分麻烦
// 但是我们都建议使用Apeache的文件上传组件来实现,common.fileupload,它需要依赖于commons-io组件
// ***************** 1.创建DiskFileItemFactory对象,处理文件上传路径或则大小限制的
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 2.通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将她放到临时文件中去
diskFileItemFactory.setSizeThreshold(1024 * 1024); //缓存大小为1MB
// 3.
diskFileItemFactory.setRepository(tempFile); //临时目录的保存目录,需要一个file
/*
ServletFileUpload负责处理上传的文件数据,并将表单中的每个输入项封装成一个Filetem对象,
在使用ServletFileUpload对象解析请求时需要DiskFileletemFactory对象。
所以,我们需要在进行解析工作前构造好DiskFileltemFactory对象,
通过servletFileUpload对象的构造方法或setFileltemFactory()方法
设置ServletFileUpload对象的FileitemFactory属性
*/
// ******************* 4.获取servletFileUpload
ServletFileUpload upload = new ServletFileUpload(diskFileItemFactory);
// 5.监听文件上传的速度
upload.setProgressListener(new ProgressListener() {
public void update(long l, long l1, int i) {
System.out.println("总大小" + l1 + "已上传:" + l);
}
});
// 处理乱码问题
upload.setHeaderEncoding("UTF-8");
// 设置单个文件的最大值
// 1024=1kb*1024=1MB*10=10MB
upload.setSizeMax(1024 * 1024 * 10);
// ******************* 6. 处理上传文件
//(1).把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
List<FileItem> fileItems = upload.parseRequest(req);
for (FileItem fileItem : fileItems) {
// 判断上传的文件是普通的表单还是带文件的表单
if (fileItem.isFormField()) { //假如说普通的表单
// 判断上传的文件是普通的表单还是带文件的表单
String fieldName = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");
System.out.println(fieldName + ":" + value);
} else { //假如是文件
//==================处理文件================//
String uploadFileName = fileItem.getName();
System.out.println("上传的文件名是:"+uploadFileName);
//可能存在文件名不合法的情况
if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue;
}
//获得上传的文件名 /imges/girl.jpg
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//获得文件的后缀名
String fileName_End = uploadFileName.substring(uploadFileName.lastIndexOf(".")+ 1);
System.out.println("文件信息【件名:"+fileName+"--->文件类型"+fileName_End+"】");
/*
如果文件后缀名fileName_End 不是我们所需要的
就直接return,不处理,告诉用户文件类型不对
*/
//可以使用UUID(唯一识别的通用码),保证文件名唯一
//UUID.randomUUID(),随机生成一个唯一识别的通用码;
//网络传输中的东西,都需要序列化
//POJO,实体类,如果想要在多个电脑上运行,需要传输====》需要把对象都序列化
String uuidPath = UUID.randomUUID().toString();
//==================存放地址================//
//存到哪? :uploadPath--->创建的文件目录
// 文件真实存在的路径:realPathFile
String realPath = uploadPath + "/" + uuidPath;
//给每个文件创建一个对应的文件夹
File realPathFile = new File(realPath);
if (!realPathFile.exists()) { //假如说不存在就创建
realPathFile.mkdir();
}
//==================文件传输================//
//获得文件上传的流
InputStream inputStream = fileItem.getInputStream();
//创建一个文件输出流
//realpath=真实的文件夹
//差一个文件,加上输出文件的名字+"/+uuidPath"
FileOutputStream fileOutputStream = new FileOutputStream(realPath + "/" + fileName);
//创建一个缓冲区
byte[] bytes = new byte[1024 * 1024];
//判断是否读取完毕
int len = 0;
//如果大于0说明还存在数
while ((len = inputStream.read(bytes)) > 0) {
fileOutputStream.write(bytes, 0, len);
}
//关闭流
fileOutputStream.close();
inputStream.close();
msg = "文件上传成功!";
fileItem.delete(); //上传成功,清楚临时文件
}
}
req.setAttribute("msg",msg);
req.getRequestDispatcher("info.jsp").forward(req,resp);
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上传资源入口</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.pic{
/*background : url("..img/back8.jng");*/
height:100%;
width: 100%;
background-size: cover;
background-repeat: no-repeat;
margin: 60px auto;
}
.contain{
box-shadow: 10px 10px 60px rgba(93, 86, 20, 0.909);
margin: 0 auto;
width: 500px;
height: 500px;
border-radius: 20px;
padding-top: 60px;
}
input.seat{
margin-top: 40px;
height: 35px;
width: 350px;
}
.input_out{
height: 54px;
width:100px;
margin-top: 41px;
background-color: #6495ED;
border-width: 0px;
font-size: 20px;
color: white;
margin-left: -5px;
border-top-right-radius: 10px; /*圆角*/
border-bottom-right-radius: 10px; /*圆角*/
border-top-left-radius:10px;
border-bottom-left-radius:10px;
}
.bjimg{
position: fixed;
top:0;
left:0;
width: 100%;
height: 100%;
z-index: -10;
/*适应*/
object-fit: cover;
}
#file{
width: 200px;
height: 100px;
}
</style>
</head>
<body>
<video src="img/1.mp4" loop autoplay class="bjimg"></video>
<div class="pic">
<div class="contain" >
<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
<div align="center">
<br/>
<strong><span style="font-size: 40px; color: white; font-family: 楷体">文件传输页面</span></strong><br></div>
<div align="center">
<br/><br/>
<input type="text" class="seat" name="username" placeholder="请输入上传用户名" id="seat"><br>
<input type="file" placeholder="上传文件" name="FileUpload" style="background: aqua" id="file"><br/>
<br/>
<input type="submit" class="input_out" onmousemove="this.className='input_move'" onmouseout="this.className='input_out'" value="开始上传">
</div>
</form>
</div>
</div>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" version="4.0" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
<!--对servlet进行配置-->
<servlet>
<servlet-name>Servlet</servlet-name>
<servlet-class>com.Jsxs.Servlet.Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
</web-app>
(二十六)、邮箱发送
1.邮箱发送的原理:
2.服务器的原理
3.下载两个jar包
JavaMail API (compat) » 1.4.7
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
JavaBeans™ Activation Framework » 1.1.1
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
4.基本类:
5.全部代码
package Com.Jsxs;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
//发送一个简单的邮件
public class MailDemo1 {
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发送邮件的五个步骤
// 1.创建定义整个应用程序所需要的环境信息的session对象
Session session=Session.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 发件人邮件用户名,授权码
return new PasswordAuthentication("2261203961@qq.com","授权码");
}
});
// 开启Session的debug模式,这样就可以看到程序发送Email的运行状态
session.setDebug(true);
// 2.通过session得到transport对象
Transport ts = session.getTransport();
// 3.使用邮箱的用户名和授权码连上邮件服务器
ts.connect("smtp.qq.com","2261203961@qq.com","授权码");
// 4.创建邮件: 写邮件
// 注意需要传递Session
MimeMessage message = new MimeMessage(session);
//指明邮件的发件人
message.setFrom(new InternetAddress("2261203961@qq.com"));
//指明邮件的收件人,发件人和收件人一样就是发送给自己
message.setRecipient(Message.RecipientType.TO,new InternetAddress("2261203961@qq.com"));
//邮件的标题
message.setSubject("吉士先生");
//邮件的文本内容:
message.setContent("<h1 style='color: red'>你好啊,李威涛<h1>","text/html;charset=UTF-8");
// 5.发送邮件
ts.sendMessage(message,message.getAllRecipients());
// 6.关闭邮件链接
ts.close();
}
}
(二十七)、网站注册发送邮件实现
package com.Jsxs.Util;
import com.Jsxs.projo.User;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Properties;
// 网站三秒原则
public class Sendmail extends Thread{
//
private String from="2261203961@qq.com";
// 邮箱的用户名
private String username="2261203961@qq.com";
// 授权码
private String password="dbiqifywbfxjdjdh";
// 发送邮件的服务器地址
private String host="smtp.qq.com";
private static User user;
public Sendmail(User user){
this.user=user;
}
public void run(){
try {
Properties prop = new Properties();
prop.setProperty("mail.host",host); // 设置QQ邮件服务器
prop.setProperty("mail.transport.protocol","smtp"); //邮件发送协议
prop.setProperty("mail.smtp.auth","true"); //需要验证用户密码
// 关于QQ邮箱,还要设置SSL加密,加上一下代码即可
MailSSLSocketFactory sf= null;
sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable","true");
prop.put("mail.smtp.ssl.socketFactory",sf);
// 使用JavaMail发送邮件的五个步骤
// 1.创建定义整个应用程序所需要的环境信息的session对象
Session session=Session.getDefaultInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 发件人邮件用户名,授权码
return new PasswordAuthentication(username,password);
}
});
// 开启Session的debug模式,这样就可以看到程序发送Email的运行状态
session.setDebug(true);
// 2.通过session得到transport对象
Transport ts = session.getTransport();
// 3.使用邮箱的用户名和授权码连上邮件服务器
ts.connect(host,username,password);
// 4.创建邮件: 写邮件
MimeMessage mimeMessage = imageMall(session);
// 5.发送邮件
ts.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
// 6.关闭邮件链接
ts.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static MimeMessage imageMall(Session session) throws MessagingException {
// 注意需要传递Session
MimeMessage mimeMessage = new MimeMessage(session);
//指明邮件的发件人
mimeMessage.setFrom(new InternetAddress("2261203961@qq.com"));
//指明邮件的收件人,发件人和收件人一样就是发送给自己
mimeMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(user.getEmail()));
//邮件的标题
mimeMessage.setSubject("用户注册");
String info="恭喜您注册成功,您的用户名为:"+user.getUsername()+",您的密码:"+user.getPassword()+",请您妥善管理";
//===================================================================图片//
//准备图片数据
MimeBodyPart image = new MimeBodyPart();
//图片需要进行处理
DataHandler dh = new DataHandler(new FileDataSource("E:\\Ideal源码\\emali\\web\\img\\3.png"));
image.setDataHandler(dh); //在我们的主题中 放入这个处理后的数据
image.setContentID("haha.jpg"); //给图片设置一个ID
//准备正文数据
MimeBodyPart text = new MimeBodyPart();
text.setContent("<img src='cid:haha.jpg'>"+info,"text/html;charset=UTF-8");
//*******************************************************************附件//
//附件
MimeBodyPart body3 = new MimeBodyPart();
body3.setDataHandler(new DataHandler(new FileDataSource("E:\\Ideal源码\\mail-java\\src\\Com\\resourece\\log4j.properties")));
body3.setFileName(""); //附件设置名字
MimeBodyPart body4 = new MimeBodyPart();
body4.setDataHandler(new DataHandler(new FileDataSource("E:\\Ideal源码\\mail-java\\src\\Com\\resourece\\1.txt")));
body4.setFileName(""); //附件设置名字
//拼装正文内容---->文本和图片
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");
//将拼接好的正文内容设置为主题
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(mm);
//拼装附件
MimeMultipart allFile = new MimeMultipart();
allFile.addBodyPart(body3); //附件1
allFile.addBodyPart(body4); //附件2
allFile.addBodyPart(contentText); //正文
allFile.setSubType("mixed"); //所有类型都设置为mixed
//设置到消息,保存修改
mimeMessage.setContent(allFile);
mimeMessage.saveChanges();
//===================================================================//
return mimeMessage;
}
}
package com.Jsxs.Servlet;
import com.Jsxs.Util.Sendmail;
import com.Jsxs.projo.User;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegisterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
System.out.println(username+" "+password+" "+email);
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setEmail(email);
Sendmail sendmail = new Sendmail(user);
sendmail.start();
//注册用户;
req.setAttribute("message","注册成功,我们已经向您发送了一封电子邮件,请您查收");
req.getRequestDispatcher("info.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
(二十八)、
1.表格提交后转达到Servlet ,那么 只需要写映射的名字即可,不用+/