副文本编辑器

一、html效果图

二、图片上传

注意:最后后端要返回JSON

java 复制代码
	<!-- 图片上传 -->
	
	<!-- 1. 图片上传区域 -->
<form class="imgbox" enctype="multipart/form-data">
    <input type="file" name="file" class="file" accept="image/*">
    <input type="hidden" class="imgurl" name="imgurl">
    <div class="show"></div>   <!-- 预览缩略图 -->
</form>

<!-- 2. jQuery:选完图就自动上传 -->
<script>
// 图片上传
$(".file").change(function () {
    var fd = new FormData($(".imgbox")[0]);      // 把表单打成二进制包
    if (!fd.get("file").name) return;            // 没选文件直接返回
    $.ajax({
        url: "/upload",          // 后端上传接口
        type: "POST",
        data: fd,
        contentType: false,
        processData: false,
        success: function (res) {
            // 假设后端返回 JSON:{imgurl:"xxx.jpg"}
            $(".show").html(
                "<img src='upload/" + res.imgurl + "' style='width:150px;height:100px;object-fit:cover'>"
            );
            $(".imgurl").val(res.imgurl);   // 把文件名塞进隐藏域
        },
        error: function () {
            alert("上传失败");
        }
    });
});
</script>

|-----------------------------------------------------------|-------------------------------------------------------------------|---|---|---|---|---|---|---|
| 代码 | 说明 | | | | | | | |
| `<form class="imgbox" enctype="multipart/form-data">` | 必须 指定 `enctype`,否则浏览器不会把文件当二进制传。 | | | | | | | |
| `<input type="file" accept="image/*">` | 只允许选图片;`accept` 只是前端提示,后端仍需校验。 | | | | | | | |
| `new FormData($(".imgbox")[0])` | 把整个表单打包成二进制对象,文件/文字一起发。 | | | | | | | |
| `contentType:false``processData:false` | 告诉 jQuery 不要 加 `Content-Type`, 也不要把 `FormData` 转字符串,让浏览器自动处理。 | | | | | | | |
| `success:function(res){...}` | 后端必须返回 JSON:`{"imgurl":"xxx.jpg"}`,否则前端拿不到字段。 | | | | | | | |

三、验证码

1.html图形验证码

生成随机验证码

验证码功能位于cn.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:

  • createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
  • getCode 获取验证码的文字内容
  • verify 验证验证码是否正确,建议忽略大小写
  • write 将验证码图片写出到目标流中

·LineCaptcha 线段干扰的验证码

javascript 复制代码
//定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);

//图形验证码写出,可以写出到文件,也可以写出到流
lineCaptcha.write("d:/line.png");
//输出code
Console.log(lineCaptcha.getCode());
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");

//重新生成验证码
lineCaptcha.createCode();
lineCaptcha.write("d:/line.png");
//新的验证码
Console.log(lineCaptcha.getCode());
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");

·CircleCaptcha 圆圈干扰验证码

java 复制代码
//定义图形验证码的长、宽、验证码字符数、干扰元素个数
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
//图形验证码写出,可以写出到文件,也可以写出到流
captcha.write("d:/circle.png");
//验证图形验证码的有效性,返回boolean值
captcha.verify("1234");

2.副文本编辑器应用

在副文本编辑器里编辑图片和表情

html 复制代码
   <!-- 加载编辑器的容器 -->
    <script id="container" name="content" type="text/plain">
    </script>
    <!-- 配置文件 -->
    <script type="text/javascript" src="utf8-jsp/ueditor.config.js"></script>
    <!-- 编辑器源码文件 -->
    <script type="text/javascript" src="utf8-jsp/ueditor.all.js"></script>
    
    <input type='button' value='获取内容' class='btn'>
    
    <div class='show'>
    
   <!--html形式解析,获取图片应该首先插入img标签-->
   <!--&nbsp不换行空格,em斜体,strong加粗,先写倾斜在写加粗-->
   <!-- 加图片的话需要路径对 -->
    
    <p>&nbsp; &nbsp; &nbsp; &nbsp;这里写<span style="color: rgb(255, 0, 0);">你的<em><strong>初始</strong></em></span><span style="color: rgb(146, 208, 80);"><em><strong>化</strong></em><em><strong>内容</strong></em> &nbsp; &nbsp;</span></p>
    </div>
    <!-- 实例化编辑器 -->
    <!--在添加页面加上一个文本框,可以上传图片和表情 -->
    <script type="text/javascript">
        var ue = UE.getEditor('container');
        $(".btn").click(function(){
        	console.log(ue.getContent())
        
        	$(".show").html(ue.getContent())
        })

四、文件上传

前端 FormData + 后端 ServletFileUpload + UUID 防重名 + JSON 回显路径

1.前端

1️⃣ 前端三件套

<form enctype="multipart/form-data">

必须声明,否则浏览器不会把文件当二进制发送。

<input type="file" accept="image/*">

仅提示格式,仍需后端校验 MIME。

AJAX 二进制上传

new FormData(form) + contentType:false + processData:false

禁止 jQuery 破坏 multipart。

2.后端

2️⃣ 后端解析框架

Apache Commons-FileUpload

ServletFileUpload + DiskFileItemFactory 官方标准解析器。

大小限制

setFileSizeMax (单文件) / setSizeMax (总大小)防止 OOM。

MIME 判断

ServletFileUpload.isMultipartContent(req) 排除普通表单。

3.后端代码

java 复制代码
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		 //设置请求和响应的编码格式
		req.setCharacterEncoding("utf-8");
		resp.setContentType("text/json;charset=UTF-8"); 
		resp.setCharacterEncoding("utf-8");
        
		//表单
		String realFileName="";
		
        //核心Api
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        
        //判断是否是muitipart/form-data类型
        if(!ServletFileUpload.isMultipartContent(req)) {
            //resp.getWriter().println("表单的enctype属性不是multipart/form-data类型");
        	System.out.println("表单的enctype属性不是multipart/form-data类型");
            return;
        }
        
        //设置单个文件上传大小
        fileUpload.setFileSizeMax(8*1024*1024); 
        //设置总上传文件大小
        fileUpload.setSizeMax(60*1024*1024);
        
        //解析请求
        try {
            List<FileItem> parseRequest = fileUpload.parseRequest(req);
            //获取数据
            for (FileItem fileItem : parseRequest) {
                //判断数据类型是不是普通的form表单字段
                if(!fileItem.isFormField()) {
                    //上传文件
                    String fileName = fileItem.getName();
                    InputStream fileStream = fileItem.getInputStream();
                    //定义保存的父路径(服务器部署的真实路径)
                    String parentDir = this.getServletContext().getRealPath("/upload");
                    //定义绝对路径
                    //String parentDir = "D:\\eclipse-workspace-new\\myWish\\WebContent\\upload";
                    //使用UUID+文件名的方式,避免文件重名
                    realFileName = UUID.randomUUID().toString()+"-"+fileName;
                    //创建要保存的文件
                    File file = new File(parentDir,realFileName);
                    //判断文件夹是否存在
                    if(!file.getParentFile().exists()) {
                        //创建文件夹[多级文件夹]file.madir是创建单一文件夹
                        file.getParentFile().mkdirs();
                    }
                    
                    //创建输出流
                    OutputStream out = new FileOutputStream(file);
                    //创建字节缓存
                    byte[] buffer = new byte[1024];
                    int len = -1;
                    //一次读取1kb(1024byte),返回-1表明读取完毕
                    while((len = fileStream.read(buffer))!=-1) {
                        //一次写入1kb(1024byte)
                        out.write(buffer,0, len);
                    }
                    System.out.println(realFileName);
                  
                    //冲刷流资源
                    out.flush();
                    //关闭流
                    out.close();
                    fileStream.close();
                    
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } 
        String json="";
        if(realFileName!=null && !"".equals(realFileName)) {
        	 json = "{\"msg\":\"上传成功\",\"imgurl\":\""+realFileName+"\"}";
        }else {
        	 json = "{\"msg\":\"上传失败\"}";
        }
		resp.getWriter().print(json);
		
	}