07-其他后端常用功能

nobility 发布于 2021-09-17 753 次阅读


其他后端常用功能

文件上传

Servlet实现文件上传需要借助fileupload或其他第三方上传工具包,fileupload是Apache commons下面的一个子项目,需要引入相关jar包,从maven官网中查找Apache Commons FileUpload并下载,以及下载相关依赖(commons-io),导入项目即可

<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
  <!-- 必须指定enctype为multipart/form-data -->
    <input type="text" name="name">
    <input type="file" name="file">
    <input type="submit" value="上传">
</form>

该工具上传步骤比较复杂,我将其提取成一个方法,该方法仅适合于单文件上传,因为Map的关系,虽然可以上传成功,但是返回的Map对象中的文件属性是最后一个文件,因为之前的被覆盖掉了

  /**
   * 解析有文件上传的表单提交,并将表单项解析成Map对象
   *
   * @param servletRequest 要解析的请求对象
   * @param dir            要上传的目录(应该是静态资源目录下的子目录,即web目录下的子目录,要保证该目录存在)
   * @return HashMap<String, String>
   * @throws IOException
   */
  private HashMap<String, String> parseRequest(ServletRequest servletRequest, String dir) throws IOException {
    /*1.fileupload中核心类的创建*/
    HashMap<String, String> hashMap = new HashMap<>();  //存储返回结果的Map对象
    HttpServletRequest req = (HttpServletRequest) servletRequest;  //向下强制转换为HttpServletRequest
    DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();  //创建磁盘文件项工厂类用于创建文件上传核心类使用
    ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);  //创建文件上传核心类
    
    /*2.fileupload的使用*/
    InputStream inputStream = null;
    FileOutputStream fileOutputStream = null;
    try {
      List<FileItem> fileItems = fileUpload.parseRequest(req);  //使用fileupload核心类解析请求
      for (FileItem fileItem : fileItems) {
        if (fileItem.isFormField()) { //若不是文件
          String name = fileItem.getFieldName();  //获取字段名
          String value = fileItem.getString("UTF-8"); //获取字段值,并防止中文乱码
          hashMap.put(name, value); //添加到Map对象中
        } else {  //若是文件
          String name = fileItem.getFieldName();  //获取字段名
          String filename = fileItem.getName();  //获取文件名
          
          /*2.1.解决文件上传重名覆盖问题*/
          int idx = filename.lastIndexOf(".");
          String exName = filename.substring(idx);  //截取文件后缀名
          filename = UUID.randomUUID().toString().replace("-", "") + exName;  //生成随机UUID拼接后缀名,修改文件名避免上传重名文件被覆盖
         
          /*2.2.文件上传的输入流对接*/
          inputStream = fileItem.getInputStream();  //获取文件的输入流
          String dirAPath = getServletContext().getRealPath(dir);  //获取上传目录的的绝对路径
          String fileRealPath = dirAPath + File.separator + filename; //将fieldName修改为上传后的文件路径
          fileOutputStream = new FileOutputStream(fileRealPath);  //根据文件名真实路径创建文件输出流
          int len = 0;
          byte[] bytes = new byte[1024];
          while ((len = inputStream.read(bytes)) != -1) {
            fileOutputStream.write(bytes, 0, len);  //1KB,1KB的写入文件
          }
          
          /*3.返回值中Map对象value值的优化拼接*/
          String fileRPath = getServletContext().getContextPath() + "/" + dir + "/" + filename; //拼接文件符合src的相对路径
          hashMap.put(name, fileRPath); //将上传后的路径添加到Map对象中
        }
      }
    } catch (FileUploadException e) {
      e.printStackTrace();
    } finally { //释放IO资源
      if (inputStream != null) {
        inputStream.close();
      }
      if (fileOutputStream != null) {
        fileOutputStream.close();
      }
    }
    return hashMap;
  }

验证码校验

Servlet实现验证码校验需要借助Kaptcha或其他第三方上传工具包,Kaptcha是一个可高度配置的实用验证码生成工具,原理就是在内存中生成一张验证码图片返回给客户端,使用需要引入相关jar包,从maven官网中查找Kaptcha并下载,以及下载相关依赖(Filters)导入项目,并在web.xml中配置即可

<servlet>
  <servlet-name>Kaptcha</servlet-name>
  <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
  <init-param>  <!-- 边框颜色 -->
    <param-name>kaptcha.border.color</param-name>
    <param-value>white</param-value>
  </init-param>
  <init-param>  <!-- 字体颜色 -->
    <param-name>kaptcha.textproducer.font.color</param-name>
    <param-value>white</param-value>
  </init-param>
  <init-param>  <!-- 干扰线的颜色 -->
    <param-name>kaptcha.noise.color</param-name>
    <param-value>black</param-value>
  </init-param>
  <init-param>  <!-- 背景渐变开始颜色 -->
    <param-name>kaptcha.background.clear.from</param-name>
    <param-value>254,67,101</param-value>
  </init-param>
  <init-param>  <!-- 背景渐变结束颜色 -->
    <param-name>kaptcha.background.clear.to</param-name>
    <param-value>252,157,154</param-value>
  </init-param>
  <init-param><!-- 图片样式添加阴影 -->
    <param-name>kaptcha.obscurificator.impl</param-name>
    <param-value>com.google.code.kaptcha.impl.ShadowGimpy</param-value>
  </init-param>
  <init-param>  <!-- 图片宽度 -->
    <param-name>kaptcha.image.width</param-name>
    <param-value>200</param-value>
  </init-param>
  <init-param>  <!-- 图片高度 -->
    <param-name>kaptcha.image.height</param-name>
    <param-value>50</param-value>
  </init-param>
  <init-param>  <!-- 字体大小 -->
    <param-name>kaptcha.textproducer.font.size</param-name>
    <param-value>45</param-value>
  </init-param>
  <init-param>  <!-- 验证码字符个数 -->
    <param-name>kaptcha.textproducer.char.length</param-name>
    <param-value>4</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>Kaptcha</servlet-name>
  <url-pattern>/kaptcha</url-pattern>
</servlet-mapping>

jsp中的表单提交代码

<form action="${pageContext.request.contextPath}/check" method="get">
    <input type="text" name="kaptcha">
    <img id="kaptcha" src="${pageContext.request.contextPath}/kaptcha" alt="">
    <input type="button" id="reset" value="看不清,换一张">
    <input type="submit" value="提交">
</form>
<script>
    var reset = document.getElementById("reset");
    reset.addEventListener("click", function () {
        var img = document.getElementById("kaptcha");
        img.src = "${pageContext.request.contextPath}/kaptcha?time=" + new Date().getTime();
        //加时间戳是为了消除浏览器缓存
    })
</script>

servlet中验证验证码是否正确代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
  String kaptcha_session_key = (String) request.getSession().getAttribute("KAPTCHA_SESSION_KEY");	//从sesion中获取真正验证码
  String kaptcha = request.getParameter("kaptcha");	//用户提交的验证码
  response.setContentType("text/html;charset=utf8");
  if (kaptcha_session_key.equals(kaptcha)) {	//比较是否相同
    response.getWriter().write("验证码通过");
  } else {
    response.getWriter().write("验证码错误");
  }
}
此作者没有提供个人介绍
最后更新于 2021-09-17