JavaWeb开发常用组件功能
常用组件化Web开发内容
1.文件的上传
(1)需要引入的 jar 文件:commons-fileupload-1.3.2、commons-io-2.5.jar。
<!-- 文件上传相关包:commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- 文件IO相关包:commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
(2)进行配置项的封装
#-- 配置参数封装成为成员变量
//1.文件上传保存在服务器地址的路径
private static final String UPLOAD_DIRECTORY = "D:\\uploadFiles";
// # 临时记忆存储大小(单位字节)
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3;
//# 最大文件大小(单位字节)
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40;
//# 最大请求大小(单位字节)
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50;
(3) 编写文件上传doPost方法
注意:文件上传请求只能使用post请求,同时文件上传需要提交文件媒体信息以及关联业务主键id
3.1 判断请求是否是包含了媒体元素上传的请求
//1.检测是否为文件媒体元素上传
boolean multipartContent = ServletFileUpload.isMultipartContent(req);
if(!multipartContent){//不是包含了文件媒体元素上传的请求
Result res = new Result();
res.setCode("9999");
res.setMsg("不是一个标准的文件上传请求");
writer.print(res.toString());
writer.flush();
writer.close();
return;
}
3.2 通过工厂类来生产文件上传对象(加载配置过程)
//2.创建工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置临界值
factory.setSizeThreshold(MEMORY_THRESHOLD);
//设置临时存储的地址
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
//生成ServletFileUpload对象
ServletFileUpload upload = new ServletFileUpload(factory);
3.3 文件上传对象配置加载
// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);
// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);
//文件内容编解码字符集设置
upload.setHeaderEncoding("UTF-8");
3.4 获取上传的文件进行文件的写出
//1.获取所有请求提交的元素内容
int uploadCont = 0;//文件上传总数计数
try {
List<FileItem> fileItems = upload.parseRequest(req);
//判断请求提交是否有内容
if(fileItems != null&&fileItems.size()>0){//如果有内容在进行上传文件
for(FileItem item : fileItems){//遍历请求项目
if (!item.isFormField()){//当表单项目内容不是一个普通表单时(就是文件)
//获取上传的文件封装为对象
System.out.println("上传中:文件名:"+item.getName());
File file = new File(item.getName());
//封装文件输出路径和对象
String outPath = UPLOAD_DIRECTORY+"\\"+file.getName();
//封装一个输出的文件对象
File outFile = new File(outPath);
//调用输出方法写出到硬盘位置
item.write(outFile);
uploadCont++;
}
}
}
} catch (Exception e) {
System.err.println("文件上传出错");
e.printStackTrace();
res.setCode("9999");
res.setMsg("文件上传出错");
writer.print(res.toString());
writer.flush();
writer.close();
return;
}
res.setCode("0000");
res.setMsg("文件上传成功!");
res.setData(uploadCont);
writer.print(res.toString());
writer.flush();
writer.close();
(4)前端文件上传方法
4.1 表单提交方法
<form action="http://localhost:8090/webDemo/uploadFiles"
method="post" #---- 有文件上传的请求只能为post请求
enctype="multipart/form-data" #--- 文件上传必须要定义
>
<input type="text" name="name" />
<input type="file" name="uploadFile" />
<input type="file" name="uploadFile2" />
<input type="submit" value="上传" />
</form>
4.2 ajax文件上传方法
<form id="myForm">
<input type="file" name="file1" />
<input type="file" name="file2" />
</form>
<button type="button" onclick="toUp()">AJAX文件上传</button>
function toUp(){
//模拟一个表单数据
console.dir($("#myForm"));
var formData = new FormData($("#myForm")[0]);
$.ajax({
url:"http://localhost:8090/webDemo/uploadFiles",
type:"POST",
data:formData,
async:false,
dataType:"JSON",
cache:false,
contentType:false,
processData:false,
success:function(data){
console.dir(data);
},
error:function(XMLHttpRequest, textStatus, errorThrown){
console.dir("请求失败!");
}
});
}
(5) 项目开发中的文件上传管理
要求:
单个业务数据能关联相关的文件信息
要设计文件与数据关联的中间表
实现:
能查询数据关联的文件
(1)设计数据与文件对应关系表
drop table if exists t_files;
/*==============================================================*/
/* Table: t_files */
/*==============================================================*/
create table t_files
(
isDelete int comment '是否删除:1:删除 0:没删除',
ipaddress varchar(50) comment '操作者IP地址',
addTime datetime comment '添加时间',
updateTime datetime comment '修改时间',
deleteTime datetime comment '删除时间',
fileID varchar(50) not null comment '文件id',
bisID varchar(50) comment '关联业务id',
filePath varchar(300) comment '文件位置',
fileName varchar(50) comment '文件名称',
fileExt varchar(50) comment '文件后缀',
fileSize varchar(50) comment '文件大小',
primary key (fileID)
);
(2) 在文件上传时保存数据,改写文件名称
for(FileItem item : fileItems){//遍历请求项目
if (!item.isFormField()){//当表单项目内容不是一个普通表单时(就是文件)
//获取上传的文件封装为对象
System.out.println("上传中:文件名:"+item.getName());
File file = new File(item.getName());
//文件后缀
String fileName = item.getName();
int i = fileName.lastIndexOf(".");
String etx = item.getName().substring(i, item.getName().length());
//生成一个UUID的文件名(同时为关联表主键字段)
String pk = UUID.randomUUID().toString().replaceAll("-","").substring(0,20);
//封装文件输出路径和对象
String outPath = UPLOAD_DIRECTORY+"\\"+pk+etx;
//调用保存文件信息到文件关联表中 !!!!关键!!!!!
saveFileData(item,etx,pk,"user1",outPath);//模拟一个业务id为user1
//封装一个输出的文件对象
File outFile = new File(outPath);
//调用输出方法写出到硬盘位置
item.write(outFile);
uploadCont++;
}
}
//保存关联信息方法
/**
* 保存业务信息与文件信息关联表
* @param item 文件对象
* @param etx 文件后缀
* @param pk 文件名称
* @param user1 关联业务id
* @param outPath 文件保存位置
*/
private void saveFileData(FileItem item,String etx, String pk, String user1,String outPath) {
Connection con = MyC3P0Util.getCon();
String sql = "INSERT INTO `t_files` VALUES\n" +
"\t( 0, NULL, NULL, NULL, NULL, ?, ?, ?, ?, ?, ? );";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1,pk);
ps.setString(2,user1);
ps.setString(3,outPath);
ps.setString(4,item.getName());
ps.setString(5,etx);
ps.setString(6,item.getSize()+"");
ps.executeUpdate();
con.close();
}catch (SQLException e){
System.err.println("保存数据到文件表异常!");
e.printStackTrace();
}
}
2.文件下载
/**
* 下载文件
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/octet-stream");
//获取客户端请求中要下载的fileID值
String fileID = req.getParameter("fileID");
//通过fileID查询要下载的文件
Connection con = MyC3P0Util.getCon();
String sql = "select * from t_files where fileID=? ";
PreparedStatement ps = null;
try {
ps = con.prepareStatement(sql);
ps.setString(1,fileID);
ResultSet resultSet = ps.executeQuery();
String filePath = "";
String fileName = "";
String fileExt = "";
while(resultSet.next()){
filePath = resultSet.getString("filePath");
fileName = resultSet.getString("fileName");
fileExt = resultSet.getString("fileExt");
}
//得到文件地址进行文件下载封装
//解决 以文件形式下载 而不会被浏览器打开 以及中文文件名需要编码
resp.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "utf-8")+fileExt);
//获取输出流
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
int available = fis.available();
System.out.println("读取大小:"+available);
byte [] arr = new byte[available];
fis.read(arr);
//如果需要使用字节流输出要使用 resp.getOutputStream()
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write(arr);
outputStream.flush();
} catch (SQLException e) {
e.printStackTrace();
}
}
3.Excel导出
XSSFWorkbook: docx、xlsx(增强兼容型文件)
HSSFWorkbook:doc、xls(旧版本的文件类型)
(1) 准备相关类库
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
(2) 实现步骤
- 创建文档对象: HSSFWorkbook
- 创建工作表对象:HSSFSheet
- 创建行对象:HSSFRow
- 创建单元格对象:HSSFCell
- 添加数据到单元格:cell.setCellValue
- 封装为文件输出:hSSFWorkbook.write
(3) 代码内容
//创建工作薄
HSSFWorkbook wb = new HSSFWorkbook();
//创建sheet对象(设置sheet名)
HSSFSheet sheet = wb.createSheet("成绩表");
//创建行 0代表第一行
HSSFRow row = sheet.createRow(0);
//在行对象中创建单元格 0代表第一列
HSSFCell cell = row.createCell(0);
//设置单元格的内容
cell.setCellValue("学生考试成绩一览表");
//合并单元格(不管是行还是列,都是从0开始)
sheet.addMergedRegion(
//设置合并的位置(起始行,截止行,起始列,截止列)
new CellRangeAddress(0,0,0,3));
//同上创建第二行
HSSFRow row1 = sheet.createRow(1);
//在第二行中添加值
row1.createCell(0).setCellValue("姓名");
row1.createCell(1).setCellValue("班级");
row1.createCell(2).setCellValue("笔试成绩");
row1.createCell(3).setCellValue("机试成绩");
//创建第三行
HSSFRow row2 = sheet.createRow(2);
//给中单元格第三行赋值
row2.createCell(0).setCellValue("张三");
row2.createCell(1).setCellValue("1807");
row2.createCell(2).setCellValue("60");
row2.createCell(3).setCellValue("60");
//创建第四行
HSSFRow row3 = sheet.createRow(3);
//给中单元格第三行赋值
row3.createCell(0).setCellValue("李四");
row3.createCell(1).setCellValue("9864");
row3.createCell(2).setCellValue("90");
row3.createCell(3).setCellValue("91");
//创建输出流
FileOutputStream outputStream = new FileOutputStream("D:\\测试.xls");
//调用工作簿的 write方法将内容写出
wb.write(outputStream);
//关闭流
outputStream.close();
4.Excel导入
(1)实现步骤:
-
创建文件输入流:FileInputStream
-
生成文档对象:Workbook
-
获取工作表对象:Sheet wb.getSheetAt(0)
-
获取总行数:sheet.getPhysicalNumberOfRows
-
遍历循环的得到行对象:row = sheet.getRow(i)
-
获取列对象:row.getCell(0)
-
获取列中的值:getStringCellValue()
(2)代码实现:
//创建输入流读取文件 FileInputStream fileIn = new FileInputStream("D:\\test.xlsx"); //创建工作簿对象 Workbook wb = new XSSFWorkbook(fileIn); //获取第一个工作表 Sheet sheet = wb.getSheetAt(0); //获取最后一行的行号 int lastRowNum = sheet.getLastRowNum(); //获取总行数 int rows = sheet.getPhysicalNumberOfRows(); //保存读取对象列表 List<Map<String,Object>> lists = new ArrayList<Map<String,Object>>(); for(int i=1;i<rows;i++){ Row row = sheet.getRow(i); Map<String,Object> map = new HashMap<>(); map.put("order",row.getCell(0).getNumericCellValue());//获取数值类型 map.put("name",row.getCell(1).getStringCellValue());//获取字符串类型 map.put("sex",row.getCell(2).getStringCellValue()); map.put("age",row.getCell(3).getNumericCellValue()); map.put("score",row.getCell(4).getNumericCellValue()); lists.add(map); } for(Map<String,Object> omap : lists){ System.out.println(omap); }
5.Java邮件发送
使用场景:
有一个公司的邮箱账号,需要批量发送邮件给其他人;
发送验证邮件信息给指定人
借助QQ邮箱服务、163邮箱服务:(IMAP/SMTP)
(1) 以QQ邮箱为例,如何打开(IMAP/SMTP)服务
打开服务,保存IMAP/SMTP 授权码
(2) java引入相关依赖
<!-- 邮件操作相关包:javax.mail-api -->
<dependency >
<groupId >com.sun.mail </groupId >
<artifactId >javax.mail </artifactId >
<version >1.5.4 </version >
</dependency >
(3) 写代码
//配置邮件服务器项目
Properties properties = new Properties();
properties.put("mail.transport.protocol", "smtp");// 连接协议
properties.put("mail.smtp.host", "smtp.qq.com");// 主机名
properties.put("mail.smtp.port", 465);// 端口号 qq邮件服务
properties.put("mail.smtp.auth", "true");//是否需要验证发送端
properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
// 得到会话对象(注意是:javax.mail.Session对象)
Session session = Session.getInstance(properties);
// 获取邮件对象
Message message = new MimeMessage(session);
// 设置发件人邮箱地址(开通了IMAP/SMTP服务的邮箱账号)
message.setFrom(new InternetAddress("760662328@qq.com"));
// 设置收件人邮箱地址(可以设置多个接收人的邮箱)
message.setRecipients(Message.RecipientType.TO,
new InternetAddress[]{
new InternetAddress("2651518027@qq.com"),
new InternetAddress("760662328@qq.com"),
new InternetAddress("508952693@qq.com"),
new InternetAddress("mou@immbj.com")
});
// 设置邮件标题
message.setSubject("java发送的一封邮件");
// 设置邮件内容
message.setText("您的验证码是:EGHY6H,不要告诉任何人。高靖博说的");
// 得到邮差对象
Transport transport = session.getTransport();
// 连接自己的邮箱账户
// 密码为QQ邮箱开通的stmp服务后得到的客户端授权码
transport.connect("760662328@qq.com", "gfxqiuhnbymcbdgb");
// 发送邮件
transport.sendMessage(message, message.getAllRecipients());
transport.close();
6.Tomcat的打包部署
(1) 打包时,静态资源文件也进入打包
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<includes>
<include>**/*.html</include>
<include>**/*.js</include>
<include>**/*.css</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
(2) 在tomcat中使用部署的是war包
打包类型配置,在pom.xml文件下
<packaging>war</packaging> # 或者 jar
使用maven-》 install 进行打包,在target目录下有打包文件
(3) 部署运行
把war包放到tomcat的webapps目录下,运行tomcat即可
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~