Java实现头像上传

实现头像上传

  • 自定义封装响应服务器数据
  • 自己创建一个Controller接口
  • 自定义控制器对象父类
  • 自己创建核心控制器
  • 封装一个文件上传的公共类
  • servlet获取上传的图片
  • servlet删除无效的图片
  • javaScript实现相关的功能

一、自定义封装响应服务器数据

package cms.project.dom.util;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/***
 * @Date(时间)2023-05-05
 * @Author 半杯可可
 *
 * 用于封装响应服务器数据
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseData {
   /**
    * 响应代码
    */
   private int code;

   /**
    * 响应消息
    */
   private String msg;

   /**
    * 响应数据
    */
   private Object data;
}

 二、自己创建一个Controller接口

package cms.project.dom.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/***
 * @Date(时间)2023-05-11
 * @Author 半杯可可
 *
 *
 * 对客户端发起请求,进行抽象接口的处理
 */
public interface Controller {

    /***
     * 核心方法
     * @param request 发起请求
     * @param response 响应数据
     * @throws ServletException
     * @throws IOException
     */

    void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;


}

三、自定义控制器对象父类

package cms.project.dom.servlet;

import cms.project.dom.util.PageVo;
import cms.project.dom.util.ResponseData;
import com.google.gson.GsonBuilder;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/***
 * @Date(时间)2023-05-11
 * @Author 半杯可可
 *
 *
 * 所有自定义控制器对象的父类 - 相关的公共操作的提取到父类,便于代码的重用
 *
 * servlet 简单封装
 */
public abstract class BaseController implements Controller{

    /**
     * 成功响应的封装 - 默认
     *
     * @param data
     * @return
     */
    public ResponseData successJson(Object data) {
        return new ResponseData(200, "", data);
    }

    /**
     * 重载方法 - 封装所有的成功响应信息
     *
     * @param code
     * @param msg
     * @param data
     * @return
     */
    public ResponseData successJson(Integer code, String msg, Object data) {
        return new ResponseData(code, msg, data);
    }

    /**
     * 错误响应的封装 - 默认
     *
     * @param msg
     * @return
     */
    public ResponseData errorJson(String msg) {
        return new ResponseData(500, msg, null);
    }

    /**
     * 重载方法 - 封装所有的错误响应信息
     *
     * @param code
     * @param msg
     * @param data
     * @return
     */
    public ResponseData errorJson(Integer code, String msg, Object data) {
        return new ResponseData(code, msg, data);
    }

    /**
     * 响应 JSON 字符串到客户端浏览器中
     *
     * @param resp
     * @param responseData
     * @throws IOException
     */
    protected void print(HttpServletResponse resp, ResponseData responseData)
            throws IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.print(new GsonBuilder()
                .setDateFormat("yyyy-MM-dd hh:mm:ss.SSS")
                .create()
                .toJson(responseData));
        out.flush();
        out.close();
    }

    /**
     * 封装PageVo - 用于 LayUI 分页
     *
     * @param count
     * @param data
     * @return
     */
    protected PageVo pageVo(Long count, Object data) {
        PageVo vo = new PageVo();
        vo.setCode(0);
        vo.setCount(count);
        vo.setData(data);
        return vo;
    }

}

四、自己创建核心控制器

package cms.project.dom.servlet;

import cms.project.dom.util.ResponseData;
import com.google.gson.GsonBuilder;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/***
 * @Date(时间)2023-05-05
 * @Author 半杯可可
 *
 * 核心控制器
 */
@WebServlet(urlPatterns = "/", loadOnStartup = 1)
@MultipartConfig
public class DispatcherServlet extends HttpServlet {
    /**
     * 收集 Controller - key为请求URL,value为Controller的完成类路径
     */
    private static final Map<Object, Object> map = new HashMap<>();

    /**
     * 加载配置文件
     *
     * @throws ServletException
     */
    @Override
    public void init() throws ServletException {
        Properties prop = new Properties();
        try {
            InputStream input = Thread.currentThread().getContextClassLoader()
                    .getResourceAsStream("config.properties");
            prop.load(input);
            prop.forEach(map::put);
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        requestURI = requestURI.replace(this.getServletContext().getContextPath(), "");
        String controllerClass = (String) map.get(requestURI);
        if (controllerClass != null) {
            Object instance = newInstance(controllerClass);
            if (instance instanceof Controller) {
                try {
                    Controller controller = (Controller) instance;
                    controller.execute(req, resp);
                } catch (Exception e) {
                    // 全局异常处理
                    handleException(resp, e);
                }
            } else {
                throw new ClassCastException(controllerClass
                        + " 转换为 cms.project.dom.controller 失败");
            }
        } else {
            req.getServletContext().getNamedDispatcher("default").forward(req, resp);
        }
    }

    /**
     * 实例化Controller
     *
     * @param className
     * @return
     * @throws ServletException
     */
    private Object newInstance(String className)
            throws ServletException {
        try {
            return Class.forName(className).getConstructor().newInstance();
        } catch (Exception e) {
            throw new ServletException(className + ":实例化失败", e);
        }
    }

    /**
     * 全局异常处理
     *
     * @param resp
     * @param e
     * @throws IOException
     */
    private void handleException(HttpServletResponse resp, Exception e)
            throws IOException {
        ResponseData responseData = new ResponseData();
        responseData.setCode(500);
        responseData.setMsg(e.getMessage());
        print(resp, responseData);
    }

    /**
     * 响应消息到客户端浏览器
     *
     * @param resp
     * @param responseData
     * @throws IOException
     */
    private void print(HttpServletResponse resp, ResponseData responseData)
            throws IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.print(new GsonBuilder()
                .setDateFormat("yyyy-MM-dd hh:mm:ss.SSS")
                .create()
                .toJson(responseData));
        out.flush();
        out.close();
    }


}

五、封装一个上传的公共类

package cms.project.dom.util;

import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/***
 * @Date(时间)2023-05-17
 * @Author 半杯可可
 *
 *
 * 文件上传公共类
 */
public class FileUploadUtil {
        /**
         * 上传文件最大容量
         */
        private long maxSize;

        /**
         * 设置允许上传文件的类型
         */
        private List<String> allowFileExt = new ArrayList<String>();

        /**
         * <p>
         * 设置默认容量和默认允许上传的文件
         * </p>
         * <p>
         * 默认允许上传1MB的文件
         * </p>
         * <p>
         * 默认允许上传的文件类型有:doc、docx、xls、xlsx、pdf、jpg、jpeg、png、gif、rar、zip
         * </p>
         */
        public FileUploadUtil() {
            // 默认允许上传1MB的文件
            this.maxSize = 1 * 1024 * 1024;
            this.setAllowFileExt("doc,docx,xls,xlsx,pdf,jpg,jpeg,png,gif,rar,zip");
        }

        /**
         * 指定最大容量和允许上传文件
         *
         * @param maxSize      最大容量
         * @param allowFileExt 允许上传文件扩展名,逗号分隔
         */
        public FileUploadUtil(long maxSize, String allowFileExt) {
            this.maxSize = maxSize;
            this.setAllowFileExt(allowFileExt);
        }

        public long getMaxSize() {
            return maxSize;
        }

        /**
         * 设置文件最大容量,默认单位为字节
         *
         * @param maxSize
         */
        public void setMaxSize(long maxSize) {
            this.maxSize = maxSize;
        }

        public List<String> getAllowFileExt() {
            return allowFileExt;
        }

        /**
         * 设置允许上传文件类型。支持多个,使用英文逗号分隔
         *
         * @param ext
         */
        public void setAllowFileExt(String ext) {
            if (ext != null && !"".equals(ext)) {
                this.allowFileExt.clear();
            }
            String[] str = ext.split(",");
            for (String s : str) {
                this.allowFileExt.add(s);
            }
        }

        /**
         * 获取上传原文件名
         *
         * @param header
         * @return
         */
        private String getFilename(String header) {
            String filename = "";
            int beginIndex = header.indexOf("filename=\"") + 10;
            int endIndex = header.lastIndexOf("\"");
            filename = header.substring(beginIndex, endIndex);
            return filename;
        }

        /**
         * 创建UUID字符串
         * <p>
         * 使用这个字符串作为上传文件的名称,以防止上传文件被替换
         *
         * @return
         */
        private String createUUID() {
            return UUID.randomUUID().toString().replace("-", "");
        }

        /**
         * 获取上传文件扩展名
         *
         * @param filename 文件名称
         * @return 文件后缀(扩展名)
         */
        private String getFileExt(String filename) {
            String value = "";

            if (filename == null || filename.lastIndexOf('.') != -1 && filename.lastIndexOf('.') == filename.length() - 1) {
                return "";
            }

            int beginIndex = filename.lastIndexOf('.') + 1;
            int endIndex = filename.length();
            value = filename.substring(beginIndex, endIndex);

            return value;
        }

        /**
         * 上传文件,文件名为UUID
         *
         * @param part
         * @param path
         * @return 返回上传文件名
         */
        public String upload(Part part, String path) {
            // 获取头信息
            String header = part.getHeader("Content-Disposition");

            // 获取上传文件的原文件名
            String filename = this.getFilename(header);

            // 获取上传文件的后缀
            String ext = this.getFileExt(filename);

            // 重新命名上传文件的名称,以防止上传文件被替换
            String newFilename = createUUID() + "." + ext;

            // 调用重载文件,实现文件上传,返回上传成功的文件名称
            return upload(part, path, newFilename);
        }

        /**
         * 上传文件
         *
         * @param part
         * @param path
         * @param flag flag为true,则文件为名UUID,flag为false,则文件名为原文件名
         * @return 返回上传文件名
         */
        public String upload(Part part, String path, boolean flag) {
            String header = part.getHeader("Content-Disposition");
            String filename = this.getFilename(header);
            String ext = this.getFileExt(filename);
            String newFilename = createUUID() + "." + ext;

            if (!flag) {
                return upload(part, path, newFilename);
            }
            return upload(part, path, filename);
        }

        /**
         * 上传文件,文件名由用户指定
         *
         * @param part 上传对象
         * @param path 上传路径
         * @param file 上传文件名称
         * @return
         */
        public String upload(Part part, String path, String file) {
            // 判断是否允许上传文件容量大小
            if (part.getSize() > this.getMaxSize()) {
                throw new RuntimeException("上传文件容量溢出,只能上传" + this.getMaxSize() / 1024 * 1024 + "字节文件");
            }

            // 获取文件后缀
            String ext = this.getFileExt(file);

            // 判断是否允许上传文件类型
            if (!this.getAllowFileExt().contains(ext)) {
                throw new RuntimeException("上传失败,只能上传文件的类型有:" + this.getAllowFileExt().toString());
            }

            // 创建上传目录
            File uploadPath = new File(path);
            if (!uploadPath.exists()) {
                uploadPath.mkdirs();
            }

            // 获取上传文件路径
            String uploadFile = path + File.separator + file;

            try {
                part.write(uploadFile);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            return file;
        }
    }

六、servlet获取上传图片

package cms.project.dom.controller.WJ;

import cms.project.dom.servlet.BaseController;
import cms.project.dom.util.FileUploadUtil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;

/***
 * @Date(时间)2023-05-17
 * @Author 半杯可可
 *  * 上传图片
 */
public class UploadProductImageController extends BaseController {

    /**
     * 默认图片:compusSLogo.png
     */
    private static final String DEFAULT_IMAGE = "compusSLogo.png";

    @Override
    public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.当前上传的图片
        Part part = req.getPart("attach");

        // 2.之前的图片
        String lastImage = req.getParameter("lastImage");

        // 获取图片上传的物理路径
        String path = req.getServletContext().getRealPath("../image");

        // 3.删除图片
        if (lastImage != null && !"".equals(lastImage)) {
            File f = new File(path + File.separator + lastImage);
            if (f.exists() && !DEFAULT_IMAGE.equals(lastImage)) {
                f.delete();
            }
        }
        // 4.使用上传工具类来实现文件的上传
        FileUploadUtil fuu = new FileUploadUtil();
        // 设置允许上传文件的大小和类型 - 1MB
        fuu.setMaxSize(1 * 1024 * 1024);
        fuu.setAllowFileExt("jpg,png,jpeg");
        String filename = fuu.upload(part, path);

        // 5.响应
        print(resp, successJson(200, "success", filename));
    }
}

七、删除无效图片

package cms.project.dom.controller.WJ;

import cms.project.dom.servlet.BaseController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

/***
 * @Date(时间)2023-05-17
 * @Author 半杯可可
 *
 * 删除无效图片
 */
public class DeleteProductImageController extends BaseController {

    // 默认图片
    private static final String DEFAULT_IMAGE = "compusSLogo.png" ;


    @Override
    public void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取无效的图片名称
        String deleteImage = req.getParameter("update_last_image");

        // 2.获取图片上传的物理路径
        String path = req.getServletContext().getRealPath("../image");

        // 3.删除图片
        if (deleteImage != null && !"".equals(deleteImage)) {
            File f = new File(path + File.separator + deleteImage);
            if (f.exists() && !DEFAULT_IMAGE.equals(deleteImage)) {
                f.delete();
            }
        }

        // 4.响应
        print(resp, successJson(200, "success", ""));
    }
}

八、JavaScript实现相关功能

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Demo</title>
    <!-- 请勿在项目正式环境中引用该 layui.css 地址 -->
    <link href="//unpkg.com/layui@2.8.3/dist/css/layui.css" rel="stylesheet">
</head>
<body>
<div class = "div_teachers display_None" id = "div_teacher"  >
    <div class="layui-form" lay-filter="filter-test-layer"  style="margin: 16px;margin-top: 40px;">
        <div class="demo-login-container">
            <div class="layui-form-item">
                <div class="layui-input-wrap">
                    <div class="layui-input-prefix">
                    </div>
                    <div style="border-radius: 5px;border: 2px solid cadetblue;width: 210px;height: 210px;text-align: center; padding: 8px;margin-top:60px;margin-left: 50px;" >
                        <img id ="pic" src="image/compusSLogo.png" class="cursor" title="资料上传" style="width: 200px;height:200px; border-radius: 5px;border:2px solid cadetblue;">
                    </div>
                </div>
            </div>
            <button id = "button_pic" style="width: 50px; height:35px;margin-left: 40px;cursor: pointer">浏览</button>
            <button  style="width: 70px; height:35px;margin-left: 40px;cursor: pointer" onclick="deleteProductImage()">取消上传</button>
        </div>
    </div>
    <!-- 用于记录上传图片的名称,用于存储在数据库中 默认:compusSLogo.png -->
    <input type="text" id="update_last_image" value="compusSLogo.png">
</div>
<!-- 请勿在项目正式环境中引用该 layui.js 地址 -->
<script src="//unpkg.com/layui@2.8.3/dist/layui.js"></script>

<script>

    // 使用 layui 相关的模块
    layui.use(['jquery', 'table', 'layer', 'form','upload'], function () {

        // 获取 LayUI 各模块的实例对象
        let $ = layui.jquery;
        let table = layui.table;
        let layer = layui.layer;
        let form = layui.form;
        let upload = layui.upload;

         // 上传图片
        let uploadInst = upload.render({
            // 绑定浏览文件元素
            elem: '#button_pic',

            // 实现上传功能的服务器端程序
            url: 'mainPage/wj/head',

            data: {
                // 动态赋值
                lastImage: function () {
                    return $("#update_last_image").val();
                }
            },

            // 设置允许上传的文件类型
            accept: 'file',

            // 设置允许上传的文件后缀
            exts: 'jpg|png|jpeg',

            // 设计允许上传文件的大小,单位:KB
            size: 10 * 1024,

            // 绑定上传控件的字段名,便于服务器获取上传文件
            field: "attach",

            // 设置不自动上传
            auto: true,

            // 上传成功的回调
            done: function (res) {
                // res参数:服务器响应回来的数据,可以封装为responseData对象
                // 上传成功后,设置文件名到隐藏域中
                if (res.code == 200) {
                    $("#update_last_image").val(res.data);
                    return;
                }
            },
            // 上传失败的回调
            error: function () {
                layer.msg('图片上传失败~~', {icon: 5});
            },
            // 选择文件后的回调
            choose: function (obj) {
                obj.preview(function (index, file, result) {
                    layer.msg('上传成功', {icon: 6});
                    // 显示图片
                    $("#pic").prop("src", result);
                });
            }
        });

    });



    // 删除无效的上传图片
    function deleteProductImage() {

        // 加载 LayUI 提供的相关模块
        layui.use(['layer', 'jquery'], function () {
            // 得到模块实例对象
            var layer = layui.layer;
            var $ = layui.jquery;


            $("#pic").prop("src", 'image/compusSLogo.png');

            // 发起异步请求,实现图片删除 - 排除默认图片
            $.ajax({
                url: 'mainPage/wj/delete_product_image',
                method: 'post',
                data: {'update_last_image': $('#update_last_image').val()},
                success: function (res) {
                    if (res.code == 200) {
                        layer.msg('成功取消', {icon: 6});
                        $('#update_last_image').val('compusSLogo.png');
                    }
                }
            });
        });
    }
</script>
</body>
</html>

我这是一个Maven项目,核心控制器需要添加一个名为‘config.properties’文件,必须是这个名

 servlet服务器地址名都在这个文件里面配置

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半杯可可

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值