前言:在最近老项目的开发中,需要做一个图片上传和点击放大的功能,在Vue和SpringBoot框架都有现成封装好的组件和工具类,对于一些上世纪的项目就没这么方便了,所以需要自己用原生的代码去编写,这里分享一下我的完整代码,亲测可用。
目录
一、项目截图
注:需要自行引入以下这四个文件
二、功能演示
点击选择文件
上传成功后
单击图片放大预览
三、JSP页面完整代码
html
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>文件上传</title>
<script type="text/javascript" src="jquery-3.7.1.min.js"></script>
</head>
<body>
<div id="image-preview"></div>
<input
type="file"
id="upload-input"
accept="image/*"
onchange="uploadImage()"
/>
<div id="outerDiv" style="position:fixed;top:0;left:0;background:rgba(0,0,0,0.7);z-index:2;width:100%;height:100%;display:none;">
<div id="innerDiv" style="position:absolute;">
<img id="bigImg" style="border:5px solid #fff;" src=""/>
</div>
</div>
</body>
<script>
function uploadImage() {
const input = document.getElementById("upload-input");
const file = input.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (event) {
const code = event.target.result;
uploadFile(file,code);
};
reader.onerror = function (error) {
console.error("Error reading the file:", error);
};
reader.readAsDataURL(file);
}
}
function uploadFile(file,code){
const formData = new FormData();
formData.append("file", file);
$.ajax({
url: 'upload',
type: 'POST',
data: formData,
async: false,
cache: false,
processData: false,// 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
success:function(res){
let imageContainer = document.getElementById('image-preview');
let uploadedImage = document.getElementById('uploaded-image');
if (uploadedImage) {
// 如果已经存在图片,则更新图片的属性
uploadedImage.setAttribute('src', code);
uploadedImage.setAttribute('alt', '');
uploadedImage.setAttribute('width', '79');
uploadedImage.setAttribute('height', '79');
} else {
// 如果不存在图片,则创建新的图片元素并添加到容器中
uploadedImage = document.createElement('img');
uploadedImage.setAttribute('id', 'uploaded-image');
uploadedImage.setAttribute('src', code);
uploadedImage.setAttribute('alt', '');
uploadedImage.setAttribute('width', '79');
uploadedImage.setAttribute('height', '79');
imageContainer.appendChild(uploadedImage);
}
console.log(imageContainer);
},
error: function(res){
}
});
}
$("#image-preview").on('click', 'img',function(event) {
let _this = $(this);//将当前的pimg元素作为_this传入函数
imgShow("#outerDiv", "#innerDiv", "#bigImg", _this);
});
function imgShow(outerDiv, innerDiv, bigImg, _this){
let src = _this.attr("src");//获取当前点击的pimg元素中的src属性
$(bigImg).attr("src", src);//设置#bigimg元素的src属性
$("<img/>").attr("src", src).on("load", function() {
let windowW = $(window).width();//获取当前窗口宽度
let windowH = $(window).height();//获取当前窗口高度
let realWidth = this.width;//获取图片真实宽度
let realHeight = this.height;//获取图片真实高度
let imgWidth, imgHeight;
let scale = 0.8;//缩放尺寸,当图片真实宽度和高度大于窗口宽度和高度时进行缩放
if(realHeight>windowH*scale) {//判断图片高度
imgHeight = windowH*scale;//如大于窗口高度,图片高度进行缩放
imgWidth = imgHeight/realHeight*realWidth;//等比例缩放宽度
if(imgWidth>windowW*scale) {//如宽度扔大于窗口宽度
imgWidth = windowW*scale;//再对宽度进行缩放
}
} else if(realWidth>windowW*scale) {//如图片高度合适,判断图片宽度
imgWidth = windowW*scale;//如大于窗口宽度,图片宽度进行缩放
imgHeight = imgWidth/realWidth*realHeight;//等比例缩放高度
} else {//如果图片真实高度和宽度都符合要求,高宽不变
imgWidth = realWidth;
imgHeight = realHeight;
}
$(bigImg).css("width",imgWidth);//以最终的宽度对图片缩放
var w = (windowW-imgWidth)/2;//计算图片与窗口左边距
var h = (windowH-imgHeight)/2;//计算图片与窗口上边距
$(innerDiv).css({"top":h, "left":w});//设置#innerdiv的top和left属性
$(outerDiv).fadeIn("fast");//淡入显示#outerdiv及.pimg
}).on("error", function() {
// Error loading image
});
$(outerDiv).click(function(){//再次点击淡出消失弹出层
$(this).fadeOut("fast");
});
}
</script>
</html>
四、Servlet完整代码
java
package com.example.javaweb;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import java.io.*;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
@WebServlet(name = "upload", value = "/upload")
public class UploadServlet extends HttpServlet {
private final int MAX_FILE_SIZE = 1024 * 1024 * 10;
private final int MAX_MEN_SIZE = 1024 * 1024 * 10;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
upload(request,response);
}catch (Exception e){
throw new RuntimeException(e);
}
}
public void upload(HttpServletRequest request, HttpServletResponse response) throws Exception {
//设置对客户端请求进行重新编码为UTF-8,否则会出现乱码
request.setCharacterEncoding("UTF-8");
//指定对服务器响应进行重新编码为UFT-8,同时浏览器也是根据这个参数来就行重写编码(又称解码)
response.setCharacterEncoding("UTF-8");
response.setContentType("text/json;charset=utf-8");
// 检查是否有一个文件上传请求
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
String savePath = "D:\\jsp\\";
if (!isMultipart) {
throw new Exception("非文件类型请求");
}
DiskFileItemFactory factory = new DiskFileItemFactory();
// 文件大小的最大值将被存储在内存中
factory.setSizeThreshold(MAX_MEN_SIZE);
// 获取项目根目录绝对路径
String path = getServletContext().getRealPath("");
// 设置缓存文件的临时存放目录
factory.setRepository(new File(path + "upload"));
ServletFileUpload upload = new ServletFileUpload(factory);
// 允许上传的文件大小的最大值
upload.setSizeMax(MAX_FILE_SIZE);
// 解析请求,获取文件项
List<FileItem> fileItems = upload.parseRequest(request);
// 处理上传的文件项
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
System.out.println(fileItem.getFieldName() + " - " + fileItem.getString("UTF-8"));
}else {
String fileName = UUID.randomUUID() +getFileType(fileItem.getName());
String fullPath = savePath+fileName;
mkdir(fullPath);
// 写入文件
File file = new File(fullPath);
fileItem.write(file);
}
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("code",200);
jsonObject.put("msg","上传成功");
response.getWriter().write(jsonObject.toString());
}
/**
* 获取文件后缀
* @param fileName
* @return
*/
public String getFileType(String fileName){
int lastIndex = fileName.lastIndexOf(".");
String fileType = "."+fileName.substring(lastIndex+1);
return fileType;
}
/**
* 创建目录
* @param path
* @throws IOException
*/
public void mkdir(String path) throws IOException {
File tempFile = new File(path);
if(!tempFile.getParentFile().exists()){
tempFile.getParentFile().mkdirs();//创建父级文件路径
tempFile.createNewFile();//创建文件
}
}
}