1.文件上传

新建空项目

准备工作

在maven仓库里下载commons io 和 commons fileupload两个jar包

实用类介绍

文件上传注意事项

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

  • 为防止文件覆盖现象发生,要为上传文件产生一个唯一的文件名:可以使用时间戳、uuid、MD5等方式解决文件重名问题

  • 要限制上传文件的最大值

  • 可以上至上传文件的类型,在收到上传文件名时,判断后缀名是否合法

需要用到的类详解

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象,在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象,所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。

FileItem类

在HTML页面中必须有name

<form action="" enctype="multipart/form-data" method="post">
上传用户:<input type="text" name="username"><br>
<p><input type="file" name="file1"></p>
<p><input type="file" name="file1"></p>
<p><input type="submit"> <input type="reset"></p>
</form>

浏览器表单的类型如果为multipart/form-data,在服务器端想要获取数据就要通过流

常用方法介绍

/*isFormField方法用于判断FIleItem类对象封装的数据是一个普通文本表单
还是一个文件表单,如果是普通表单字段则返回true,否则返回false*/
boolean isFormField(); //getName方法用于获得文件上传字段中的文件名
String getName(); //以流的形式返回上传文件的数据内容
InputStream getInputStream(); //delete方法用来清空FileItem类对象中存放的主体内容
//如果主体内容被保存在临时文件中,delete方法将删除该临时文件
void delete();

ServletFileUpload类

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中,使用其parseRequest(HttpServletRequest)方法可以将通过表单中每一个Html标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回,使用该方法处理上传文件简单易用

代码编写

FileServlet代码

package com.tang.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 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 FileServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //判断上传的文件是普通表单还是带文件的表单
if(!ServletFileUpload.isMultipartContent(req)){
return;//终止方法运行,说明这是一个普通表单,直接返回
} //创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件
String uploadPath = this.getServletContext().getRealPath("WEB-INF/upload");
File uploadFile = new File(uploadPath);
if(!uploadFile.exists()){//若文件不存在
uploadFile.mkdir();//创建这个目录
} //缓存,临时文件
//临时路径,假如文件超过了预期的大小,我们就把他放到一个临时文件中,过几天自动删除,或则提醒用户转存为永久
String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmp");
File file = new File(tmpPath);
if(!file.exists()){//若文件不存在
file.mkdir();//创建这个临时目录
} /*处理上传的文件,一般都需要通过流来获取,我们可以使用req.getInputStream(),原生态的文件上
* 传流获取,十分麻烦,但是我们都是建议使用Apache的文件上传组件来实现,common-fileupload,他需要依赖于commons-io组件*/ try {
//1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;
DiskFileItemFactory factory = getDiskFileItemFactory(file);
//2、获取ServletFileUpload
ServletFileUpload upload = getServletFileUpload(factory);
//3、处理上传文件。
String msg = uploadParseRequest(upload,req,uploadPath);
//Servlet请求转发消息
req.setAttribute("msg",msg);
req.getRequestDispatcher("/info.jsp").forward(req,resp);
}catch (FileUploadException e) {
e.printStackTrace();
} } public static DiskFileItemFactory getDiskFileItemFactory(File file){
//1、创建DiskFileItemFactory对象,处理文件上传路径或限制文件大小.
DiskFileItemFactory factory = new DiskFileItemFactory();
//通过这个工厂设置一个缓冲区,当上传的文件大小大于缓冲区的时候,将它放到临时文件中;
//这里不设置的话也有默认的。
factory.setSizeThreshold(1024 * 1024);//缓冲区大小为1M.
factory.setRepository(file);
return factory;
} public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){
//2、获取ServletFileUpload。
ServletFileUpload upload = new ServletFileUpload(factory);
//监听文件上传进度。
upload.setProgressListener(new ProgressListener() {
public void update(long pBytesRead, long lpContentLenght, int i) {
//pBytesRead:已读取到的文件大小。
//pContentLenght:文件大小。
System.out.println("总大小:"+lpContentLenght+"已上传:"+pBytesRead);//在这里还可以加进度。
}
});
//处理乱码问题.
upload.setHeaderEncoding("UTF-8");
//设置单个文件的最大值.
upload.setFileSizeMax(1024 * 1024 * 10);
//设置总共能够上传文件的大小.
//1024 = 1kb * 1024 = 1M * 10 = 10M
upload.setSizeMax(1024 * 1024 * 10);
return upload;
} public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest req,String uploadPath) throws IOException, FileUploadException {
String msg = "";
//3、处理上传文件。
//把前端的请求解析,封装成一个FileItem对象,需要从ServletFileUpLoad对象中获取
List<FileItem> fileItems = upload.parseRequest(req);
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;
}
//获得上传的文件名,例如/img/girl/ooa.jpg,只需要ooa,其前面的后面的都不需要。
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//获得文件的后缀名。
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); /*
如果文件后缀名fileExtName不是我们所需要的。
就直接return,不处理,告诉用户文件类型不对。
*/
/*可以使用UUID(唯一识别的通用码),保证文件名唯一。
UUID.randomUUID,随机生一个唯一识别的通用码。
网络传输中的东西,都需要序列化。
pojo,实体类,如果想要在多个电脑运行,传输--->需要把对象都序列化了。
JNI=java Native Interface
implements Serializable :标记接口,JVM--->java栈 本地方法栈 native-->c++ */
String uuidPath= UUID.randomUUID().toString();
System.out.println("文件信息【文件名:"+fileName+"文件类型:"+fileExtName+"】");
//======================存放地址=======================//
//存到哪?uploadPath
//文件真实存在的路径 realPath
String realPath = uploadPath+"/"+uuidPath;
//给每一个文件创建一个对应的文件夹
File realPathFile = new File(realPath);
if(!realPathFile.exists()){
realPathFile.mkdir();
}
//======================文件传输=======================//
//获得文件上传的流
InputStream inputStream = fileItem.getInputStream(); //创建一个文件输出流
FileOutputStream 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;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

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>FileServlet</servlet-name>
<servlet-class>com.tang.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
</web-app>

index.jsp

<%--
Created by IntelliJ IDEA.
User: twq
Date: 2022/8/3
Time: 17:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--通过表单上传文件
get:上传文件大小有限制
post:上传文件大小没有限制
--%>
<%--${pageContext.request.contextPath}获取服务器路径--%>
<form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
上传用户:<input type="text" name="username"><br>
<p><input type="file" name="file1"></p>
<p><input type="file" name="file1"></p>
<p><input type="submit"> <input type="reset"></p>
</form>
</body>
</html>

info.jsp


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

运行结果图

2.邮件发送

电子邮件

  • 要在网络上实现邮件功能,必须要有专门的邮件服务器。

  • 这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。

  • SMTP服务器地址:一般是 smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。

  • 电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请。比如我们要使用QQ邮箱,就需要开通邮箱功能。

传输协议

SMTP协议

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

POP3协议

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

邮件收发送原理图



原理图的描述:

  • 大Twq通过smtp协议连接到smtp服务器,然后发送一封邮件给网易的邮件服务器.

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

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

  • 小Twq通过Pop3协议连接到Pop3服务器收取邮件.

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

  • Pop3服务器将取出来的邮件送到小Twq手中.

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

8月4号继续更新

Javaweb-文件上传和邮件发送的更多相关文章

  1. SpringBoot项目实现文件上传和邮件发送

    前言 本篇文章主要介绍的是SpringBoot项目实现文件上传和邮件发送的功能. SpringBoot 文件上传 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码. 开发准备 环境要 ...

  2. Flask—04-文件上传与邮件发送(自带优化)

    文件上传与邮件发送 可以按照标题分别直接粘贴对应的文件夹,运行直接用: 原生上传 模板文件 <form method="post" enctype="multipa ...

  3. Silverlight 2中实现文件上传和电子邮件发送

    Silverlight 2中实现文件上传和电子邮件发送 [收藏此页] [打印]   作者:IT168 TerryLee  2008-05-30 内容导航: 使用Web Service上传文件   [I ...

  4. .JavaWeb文件上传和FileUpload组件使用

    .JavaWeb文件上传 1.自定义上传 文件上传时的表单设计要符合文件提交的方式: 1.提交方式:post 2.表单中有文件上传的表单项:<input type="file" ...

  5. JavaWeb——文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  6. JavaWeb 文件 上传 下载

    文件上传下载对于一个网站来说,重要性不言而喻.今天来分享一个JavaWeb方式实现的文件上传下载的小例子. 项目依赖 项目目录 工作流程 文件上传 表单处的设置 服务器端 上传功能的实现 upload ...

  7. 【Java】JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  8. JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  9. JavaWeb 文件上传下载

    1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...

随机推荐

  1. 【低码】asp.net core 实体类可生产 CRUD 后台管理界面

    前言介绍 喜欢小规模团队的"单打独斗",有的时候即使在大公司,也经常做着3-5个人团队的小项目,相信很多人有类似的经历. 本文介绍如何将项目中已存在的[实体类],直接生产出 CRUD 后台管理界面. ...

  2. Mac下最好用的SSH连接客户端 (Termius)

    Termius是微软的一款SSH终端工具,它支持多平台.而且操作界面十分ha好看且简洁,今天分享给大家️ 软件下载 关注下方公众号,回复termius获取下载地址   软件功能介绍 Termius M ...

  3. 浅谈BSGS和EXBSGS

    我的 BSGS 和各位犇犇的差不多,但是不需要求逆元 Luogu [ TJOI2007 ] 可爱的质数 原题展现 题目描述 给定一个质数 \(p\),以及一个整数 \(b\),一个整数 \(n\),现 ...

  4. GDB的简单使用一

    GDB的简单使用一 一.概念 二.GDB的基本使用方法一 调试前预备知识 获取进程的内核转储 启动gdb调试 1.启动 2.设置断点 3.运行程序 4.显示栈帧 5.显示变量 6.显示寄存器 7.单步 ...

  5. django框架12

    内容概要 csrf相关装饰器 基于中间件思想编写项目 auth认证模块 auth模块方法大全 auth扩展表字段 项目开发流程 bbs数据表分析 内容详情 csrf相关装饰器 基于中间件思想编写项目 ...

  6. Python中plt.plot()、plt.scatter()和plt.legend函数的用法示例

    参考:http://www.cppcns.com/jiaoben/python/471948.html https://blog.csdn.net/weixin_44825185/article/de ...

  7. OAuth2学习中的一些高频问题的QA

    关于OAuth2相信很多初学者都有一些疑问,胖哥将这些疑问一一收集了起来做成了QA,或许能帮助学习者. OAuth2相关的QA Q:OAuth2 的一些常用场景? A: OAuth2主要用于API授权 ...

  8. c++ 超大整数除法 高精度除法

    c++ 超大整数除法 高精度除法 解题思路 计算a/b,其中a为大整数,b为普通整数,商为c,余数为r. 根据手算除法的规则,上一步的余数记为r,则本次计算的被除数为t=r*10+被除数的本位数值a[ ...

  9. 驱动开发实战之TcpClient

    场景模拟 假设你有一批非标设备需要对接,对方提供了如下协议文档: 协议概述 设备作为TCPServer,端口6666 字节序:Little-Endian,即低地址存放低位 请求回复 需要你主动发起读取 ...

  10. Spring框架系列(3) - 深入浅出Spring核心之控制反转(IOC)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了IoC的基础含义,同时以此发散了一些IoC相关知识点; 本节将在此基础上进一步解读IOC的含义以及IOC的使用方式.@pd ...