WEB文件上传之apache common upload使用(一)

文件上传一个经常用到的功能,它有许多中实现的方案。

页面表单 + RFC1897规范 + http协议上传

页面控件(flash/html5/activeX/applet) + RFC1897规范 + http协议上传

页面控件(flash/html5/activeX/applet) + 自定义数据规范 + http协议上传

页面控件(flash/html5/activeX/applet) + FTP协议上传

页面控件(flash/html5/activeX/applet) + 自定义协议

 

  用apache common upload组件实际就是采用的“页面表单 + RFC1897规范 + http协议上传”实现方式,需要实现的技术点:

1. 多文件数据的提交

2. 文件数据包接收存储功能

3. 文件数据上传进度

4. WEB页面无刷新异步提交

 

 时序图:

  • 文件上传时序图


  • 文件上传进度获取时序图

实现思路:

1. 多文件数据的提交

在WEB页面采用多个<input type="file">利用form表单进行文件提交

 

2. 文件数据包接收存储功能

服务端采用servlet,利用apache common upload组件接收解析数据包,接收解析的过程中保存进度到session, 文件接收完毕后保存到指定目录

 

3. 文件数据上传进度

在WEB页面在界面写一个定时器,定时访问服务器提供上传进度获取功能的servlet,获取文件上传进度信息

 

4. WEB页面无刷新异步提交

利用iframe来实现WEB页面无刷新异步上传

 

关键代码:

UploadFileServlet.java

Java代码 

 收藏代码

  1. package com.test.servlet;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.Writer;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8.   
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.http.HttpServlet;  
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpServletResponse;  
  13.   
  14. import org.apache.commons.fileupload.FileItem;  
  15. import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;  
  16. import org.apache.commons.fileupload.disk.DiskFileItemFactory;  
  17. import org.apache.commons.fileupload.servlet.FileCleanerCleanup;  
  18. import org.apache.commons.fileupload.servlet.ServletFileUpload;  
  19. import org.apache.commons.io.FileCleaningTracker;  
  20. import org.apache.commons.io.FileUtils;  
  21. import org.apache.commons.io.FilenameUtils;  
  22. import org.apache.commons.io.IOUtils;  
  23. import org.apache.commons.lang3.ArrayUtils;  
  24. import org.apache.commons.logging.Log;  
  25. import org.apache.commons.logging.LogFactory;  
  26.   
  27. /** 
  28.  * 文件上传数据接收类 
  29.  *  
  30.  * @author chengqi 
  31.  * 
  32.  */  
  33. public class UploadFileServlet extends HttpServlet {  
  34.   
  35.     /** 日志对象*/  
  36.     private Log logger = LogFactory.getLog(this.getClass());  
  37.   
  38.     private static final long serialVersionUID = 1L;  
  39.   
  40.     /** 上传目录名*/  
  41.     private static final String uploadFolderName = "uploadFiles";  
  42.   
  43.     /** 上传临时文件存储目录*/  
  44.     private static final String tempFolderName = "tempFiles";  
  45.   
  46.     /** 上传文件最大为30M*/   
  47.     private static final Long fileMaxSize = 30000000L;   
  48.   
  49.     /** 允许上传的扩展名*/  
  50.     private static final String [] extensionPermit = {"txt", "xls", "zip"};  
  51.   
  52.     /** 统一的编码格式*/  
  53.     private static final String encode = "UTF-8";  
  54.   
  55.     @Override  
  56.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  57.         logger.info("UploadFileServlet#doPost() start");  
  58.         try {  
  59.             String curProjectPath = this.getServletContext().getRealPath("/");  
  60.             String saveDirectoryPath = curProjectPath + "/" + uploadFolderName;  
  61.             String tempDirectoryPath = curProjectPath + "/" + tempFolderName;  
  62.             File saveDirectory = new File(saveDirectoryPath);  
  63.             File tempDirectory = new File(tempDirectoryPath);  
  64.             logger.debug("Project real path [" + saveDirectory.getAbsolutePath() + "]");  
  65.             //上传时产生的临时文件的默认保存目录  
  66.             logger.debug("Temp files default save path [" + System.getProperty("java.io.tmpdir") + "]");  
  67.             DiskFileItemFactory factory = new DiskFileItemFactory();  
  68.             //DiskFileItemFactory中DEFAULT_SIZE_THRESHOLD=10240表示如果上传文件大于10K则会产生上传临时文件  
  69.             //上传临时文件的默认目录为java.io.tmpdir中保存的路径,根据操作系统的不同会有区别  
  70.               
  71.             if(!tempDirectory.exists()) {  
  72.                 tempDirectory.mkdir();  
  73.             }  
  74.             //重新设置临时文件保存目录  
  75.             factory.setRepository(tempDirectory);  
  76.   
  77.             //设置文件清除追踪器,文件上传过程中产生的临时文件会在  
  78.             FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(this.getServletContext());  
  79.             factory.setFileCleaningTracker(fileCleaningTracker);  
  80.   
  81.             ServletFileUpload upload = new ServletFileUpload(factory);  
  82.   
  83.             //设置文件上传进度监听器  
  84.             FileProcessListener processListener = new FileProcessListener(request.getSession());  
  85.             upload.setProgressListener(processListener);  
  86.   
  87.             // 设置文件上传的大小限制  
  88.             upload.setFileSizeMax(fileMaxSize);  
  89.   
  90.             // 设置文件上传的头编码,如果需要正确接收中文文件路径或者文件名  
  91.             // 这里需要设置对应的字符编码,为了通用这里设置为UTF-8  
  92.             upload.setHeaderEncoding(encode);  
  93.   
  94.             //解析请求数据包  
  95.             List<FileItem> fileItems = upload.parseRequest(request);  
  96.             //遍历解析完成后的Form数据和上传文件数据  
  97.             for (Iterator<FileItem> iterator = fileItems.iterator(); iterator.hasNext();) {  
  98.                 FileItem fileItem = iterator.next();  
  99.                 String fieldName = fileItem.getFieldName();  
  100.                 String name = fileItem.getName();  
  101.                 //如果为上传文件数据  
  102.                 if(!fileItem.isFormField()) {  
  103.                     logger.debug("fieldName[" + fieldName + "] fileName[" + name + "] ");  
  104.                     if(fileItem.getSize() > 0) {  
  105.                         String fileExtension = FilenameUtils.getExtension(name);  
  106.                         if(!ArrayUtils.contains(extensionPermit, fileExtension)) {  
  107.                             throw new NoSupportExtensionException("No Support extension.");  
  108.                         }  
  109.                         String fileName = FilenameUtils.getName(name);  
  110.                         FileUtils.copyInputStreamToFile(fileItem.getInputStream(),   
  111.                                 new File(saveDirectory, fileName));  
  112.                     }  
  113.                 } else { //Form表单数据  
  114.                     String value = fileItem.getString(encode);  
  115.                     logger.debug("fieldName[" + value + "] fieldValue[" + fieldName + "]");  
  116.                 }  
  117.             }  
  118.             responseMessage(response, State.OK);  
  119.         } catch(FileSizeLimitExceededException e) {   
  120.             logger.error(e.getMessage(), e);  
  121.             responseMessage(response, State.OVER_FILE_LIMIT);  
  122.         } catch(NoSupportExtensionException e) {   
  123.             logger.error(e.getMessage(), e);  
  124.             responseMessage(response, State.NO_SUPPORT_EXTENSION);  
  125.         } catch(Exception e) {  
  126.             logger.error(e.getMessage(), e);  
  127.             responseMessage(response, State.ERROR);  
  128.         } finally {  
  129.             //清除上传进度信息  
  130.             request.getSession().removeAttribute("fileUploadProcess");  
  131.         }  
  132.         logger.info("UploadFileServlet#doPost() end");   
  133.     }  
  134.   
  135.     public enum State {  
  136.         OK(200, "上传成功"),  
  137.         ERROR(500, "上传失败"),  
  138.         OVER_FILE_LIMIT(501, "超过上传大小限制"),  
  139.         NO_SUPPORT_EXTENSION(502, "不支持的扩展名");  
  140.   
  141.         private int code;  
  142.         private String message;  
  143.         private State(int code, String message) {  
  144.             this.code = code;  
  145.             this.message = message;  
  146.         }  
  147.   
  148.         public int getCode() {  
  149.             return code;  
  150.         }  
  151.         public String getMessage() {  
  152.             return message;  
  153.         }  
  154.   
  155.     }  
  156.   
  157.     /** 
  158.      * 返回结果函数 
  159.      * @param response 
  160.      * @param state 
  161.      */  
  162.     private void responseMessage(HttpServletResponse response, State state) {  
  163.         response.setCharacterEncoding(encode);  
  164.         response.setContentType("text/html; charset=" + encode);  
  165.         Writer writer = null;  
  166.         try {  
  167.             writer = response.getWriter();  
  168.             writer.write("<script>");  
  169.             writer.write("window.parent.fileUploadCallBack({\"code\":" + state.getCode() +",\"message\":\"" + state.getMessage()+ "\"});");  
  170.             writer.write("</script>");  
  171.             writer.flush();  
  172.             writer.close();  
  173.         } catch(Exception e) {  
  174.             logger.error(e.getMessage(), e);  
  175.         } finally {  
  176.             IOUtils.closeQuietly(writer);  
  177.         }  
  178.     }  
  179.   
  180.   
  181. }  

  

 

GetFileProcessServlet.java

Java代码 

 收藏代码

  1. package com.test.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.Writer;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import org.apache.commons.io.IOUtils;  
  12. import org.apache.commons.logging.Log;  
  13. import org.apache.commons.logging.LogFactory;  
  14.   
  15. /** 
  16.  * 文件上传进度获取Servlet 
  17.  *  
  18.  * @author chengqi 
  19.  * 
  20.  */  
  21. public class GetFileProcessServlet extends HttpServlet {  
  22.   
  23.     /** 日志对象*/  
  24.     private Log logger = LogFactory.getLog(this.getClass());  
  25.   
  26.     private static final long serialVersionUID = 1L;  
  27.   
  28.     @Override  
  29.     protected void doGet(HttpServletRequest request, HttpServletResponse response)  
  30.             throws ServletException, IOException {  
  31.         logger.info("GetFileProcessServlet#doGet start");  
  32.         String fileUploadPercent = (String)request.getSession().getAttribute("fileUploadProcess");  
  33.         Writer writer = null;  
  34.         try {  
  35.             writer = response.getWriter();  
  36.             logger.info("percent:" + fileUploadPercent);  
  37.             IOUtils.write(fileUploadPercent == null ? "0%" : fileUploadPercent, writer);  
  38.             writer.flush();  
  39.             writer.close();  
  40.         } catch(Exception e) {  
  41.             logger.error(e.getMessage(), e);  
  42.         } finally {  
  43.             IOUtils.closeQuietly(writer);  
  44.         }  
  45.         logger.info("GetFileProcessServlet#doGet end");  
  46.     }  
  47.   
  48. }  

 

FileProcessListener.java

Java代码 

 收藏代码

  1. package com.test.servlet;  
  2.   
  3. import java.text.NumberFormat;  
  4.   
  5. import javax.servlet.http.HttpSession;  
  6.   
  7. import org.apache.commons.fileupload.ProgressListener;  
  8. import org.apache.commons.logging.Log;  
  9. import org.apache.commons.logging.LogFactory;  
  10.   
  11. /** 
  12.  * 文件进度监听器 
  13.  *  
  14.  * @author chengqi 
  15.  * 
  16.  */  
  17. public class FileProcessListener implements ProgressListener{  
  18.   
  19.     /** 日志对象*/  
  20.     private Log logger = LogFactory.getLog(this.getClass());  
  21.   
  22.     private HttpSession session;  
  23.   
  24.     public FileProcessListener(HttpSession session) {  
  25.         this.session = session;    
  26.     }  
  27.       
  28.   
  29.     public void update(long pBytesRead, long pContentLength, int pItems) {  
  30.         double readByte = pBytesRead;  
  31.         double totalSize = pContentLength;  
  32.         if(pContentLength == -1) {  
  33.             logger.debug("item index[" + pItems + "] " + pBytesRead + " bytes have been read.");  
  34.         } else {  
  35.             logger.debug("item index[" + pItems + "] " + pBytesRead + " of " + pContentLength + " bytes have been read.");  
  36.             String p = NumberFormat.getPercentInstance().format(readByte / totalSize);  
  37.             session.setAttribute("fileUploadProcess", p);  
  38.         }  
  39.     }  
  40.   
  41. }  

 

 

apacheUploadDemo.html

 

Html代码 

 收藏代码

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3. <head>  
  4.     <title>Apache common实现基本文件上传</title>  
  5.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6.     <script type="text/javascript" src="js/jquery/jquery-1.9.1.js"></script>  
  7.     <script type="text/javascript" src="js/jquery/jquery.form.js"></script>  
  8.     <script type="text/javascript">  
  9.   
  10.     //定时器对象  
  11.     var uploadProcessTimer = null;  
  12.   
  13.     $(function (){  
  14.         //绑定定时器开始操作到提交按钮  
  15.         $('input[type=submit]').click(function () {  
  16.             //启动上传进度查询定时器  
  17.             uploadProcessTimer = window.setInterval(getFileUploadProcess, 20);  
  18.         })  
  19.     });  
  20.   
  21.     //获取文件上传进度  
  22.     function getFileUploadProcess() {  
  23.         $.get('/upload/getFileProcessServlet', function(data) {  
  24.             $('#fileUploadProcess').html(data);  
  25.         });  
  26.     }  
  27.   
  28.     //上传完成后,由iframe返回脚本自动调用  
  29.     function fileUploadCallBack(res) {  
  30.         //清除定时器  
  31.         if(uploadProcessTimer) {  
  32.             window.clearInterval(uploadProcessTimer);  
  33.         }  
  34.         var message = res['message'];  
  35.         var code = res['code'];  
  36.         if(code != 200) {  
  37.             $('#fileUploadProcess').html('0%');  
  38.         }  
  39.         alert(message);  
  40.     }  
  41.   
  42.     </script>  
  43. </head>  
  44. <body>  
  45. <h2>上传文件1</h2>  
  46.   
  47. 用户信息:  <br/>  
  48. <form id="testForm" action="/upload/uploadServlet" method="post" enctype="multipart/form-data" target="iframeUpload">  
  49.     姓名:<input name="name" type="text"> <br/>  
  50.     附件1:<input name="file1" type="file" > <br/>  
  51.     附件2:<input name="file2" type="file" > <br/>  
  52.     <br><br>  
  53.     <input type="submit" value="提交" ><br/>  
  54. </form>  
  55. 上传进度:<label id="fileUploadProcess"></label>  
  56. <iframe name="iframeUpload" src="" width="350" height="35" frameborder=0  SCROLLING="no" style="display:NONE"></iframe>     
  57. </body>  
  58. </html>  

 
总结:

虽然使用apache common upload组件实现了文件上传,但是从上传的效果来看,并不是一个很完美的解决方案。

有如下缺点:

1. 当有多个文件上传时,无法知道单个文件的上传进度,因为文件上传消息中根本就没有关于单个文件大小的信息

文件上传消息

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 22 Apr 2014 07:45:45 GMT

POST /upload/uploadServlet HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/upload/apacheUploadDemo.html
Cookie: JSESSIONID=33498CE814284D67F957CA53D45F0174
Connection: keep-alive

Content-Length 2363
Content-Type multipart/form-data; boundary=---------------------------189163093917262

-----------------------------189163093917262
Content-Disposition: form-data; name="name" 

-----------------------------189163093917262
Content-Disposition: form-data; name="file1"; filename="New Text Document.txt" Content-Type: text/plain
文件数据

-----------------------------189163093917262
Content-Disposition: form-data; name="file2"; filename="New Text Document (2).txt" Content-Type: text/plain
文件数据

-----------------------------189163093917262--

  

 2. 浏览器必须将所有文件读取完毕才开始上传,并且是一次性提交所有的数据文件,在互联网环境下,会http连接超时,大文件无法上传成功。

 

3. 服务端判断是否超过大小限制,是通过计算接收数据的累积字节数和限制大小比较,这种情况下,如果限制大小是30M,那么在服务端已经读取了30M完成后才会抛出异常,多余的消耗的服务器的内存和硬盘空间

 

所以基于这些原因,页面表单 + RFC1897规范 + http协议上传 + 后台apache common upload组件接收的这种解决方案,不适合解决WEB页面一次多文件上传,大文件上传情况,比较适合一次单个小文件附件的情况,如:博客附件,登记照片上传,预览等情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端CSS学习笔记

一 CSS介绍 层叠样式表(英文全称&#xff1a;Cascading Style Sheets)是一种用来表现HTML&#xff08;超文本标记语言&#xff09;或XML&#xff08;标准通用标记语言的一个子集&#xff09;等文件样式的计算机语言。CSS不仅可以静态地修饰网页&#xff0c;还可以配合各种脚本语…

Java爬取并下载酷狗音乐

本文方法及代码仅供学习&#xff0c;仅供学习。 案例&#xff1a; 下载酷狗TOP500歌曲&#xff0c;代码用到的代码库包含&#xff1a;Jsoup、HttpClient、fastJson等。 正文&#xff1a; 1、分析是否可以获取到TOP500歌单 打开酷狗首页&#xff0c;查看TOP500&#xff0c;发现存…

Webpack/Vue-cli两种方式加载markdown文件并实现代码高亮

准备的资源&#xff1a; highlight.js &#xff1a; 实现代码高亮&#xff0c;通过npm install highlight.js -D安装 vue-markdown-loader&#xff1a;解析md文件的必备loader&#xff0c;通过npm install vue-markdown-loader -D安装 下面我们分两个场景来说明一下md文件的…

新浪微博第三方登陆重定向错误23123

新浪微博第三方登陆重定向错误23123 2019年06月02日 13:49:43 温室花朵 阅读数&#xff1a;2更多 个人分类&#xff1a; 第三方微博登陆21323编辑当我们使用微博第三方登陆的时候&#xff0c;发现登陆出错了&#xff0c;错误码为&#xff1a;21323&#xff0c;解决方案如下&…

Utility Manager 的一些百度不了的操作

一进来是不是这样的&#xff01; 那突然出了点问题&#xff0c;咋办呢&#xff01; 就像这样子的&#xff0c; 恢复默认布局就OK啦&#xff01;哈哈哈&#xff0c;太聪明啦&#xff0c;但是百度了好长时间还是找不到啊&#xff0c;怎么办呐&#xff0c;烦死啦&#xff01; 其实…

记录一次内网渗透试验

0x00 前言 目标&#xff1a;给了一个目标机ip&#xff0c;要求得到该服务器权限&#xff0c;并通过该ip渗透至内网控制内网的两台服务器 攻击机&#xff1a;kali (192.168.31.51) 目标机&#xff1a;windows 2003 (192.168.31.196) 0x01 信息收集 nmap端口探测 御剑后台扫描 …

2018-2019 1 20165203 实验五 通用协议设计

2018-2019 1 20165203 实验五 通用协议设计 OpenSSL学习 定义&#xff1a;OpenSSL是为网络通信提供安全及数据完整性的一种安全协议&#xff0c;囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议&#xff0c;并提供了丰富的应用程序供测试或其它目的使用。基本功…

弄懂webpack,只要看这一片就够了(文末有福利)

什么是webpack ​ webpack是什么&#xff0c;官网中是这么说的。 ​ 本质上&#xff0c;webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时&#xff0c;它会递归地构建一个依赖关系图(dependency graph)&#xff0c;其中包…

beta冲刺总结那周余嘉熊掌将得队

作业格式 课程名称&#xff1a;软件工程1916|W&#xff08;福州大学&#xff09;作业要求&#xff1a;项目Beta冲刺团队名称&#xff1a; 那周余嘉熊掌将得队作业目标&#xff1a;beta冲刺总结队员学号队员姓名博客地址备注221600131Jaminhttps://www.cnblogs.com/JaminWu/队长…

在Winform中菜单动态添加“最近使用文件”

最近在做文件处理系统中&#xff0c;要把最近打开文件显示出来&#xff0c;方便用户使用。网上资料有说&#xff0c;去遍历“C:\Documents and Settings\Administrator\Recent”下的最近文档本。文主要介绍在Winform界面菜单中实现【最近使用的文件】动态菜单的处理&#xff0c…

Vue组件通信原理剖析(一)事件总线的基石 $on和$emit

首先我们先从一个面试题入手。 面试官问&#xff1a; “Vue中组件通信的常用方式有哪些&#xff1f;” 我答&#xff1a; 1. props 2. 自定义事件 3. eventbus 4. vuex 5. 还有常见的边界情况$parent、$children、$root、$refs、provide/inject 6. 此外还有一些非props特性$att…

display:flex弹性布局

一、背景 前段时间帮公司运维小姑娘调整她自己写的页面样式时发现她用了display: flex&#xff0c;我这个后端老古董还不太懂flex&#xff0c;自愧不如啊&#xff0c;所以写篇博客记录学习下。 现在写的前端页面还停留在依赖 display 属性 position属性 float属性的布局方式&…

Vue组件通信原理剖析(二)全局状态管理Vuex

首先我们先从一个面试题入手。 面试官问&#xff1a; “Vue中组件通信的常用方式有哪些&#xff1f;” 我答&#xff1a; 1. props 2. 自定义事件 3. eventbus 4. vuex 5. 还有常见的边界情况$parent、$children、$root、$refs、provide/inject 6. 此外还有一些非props特性$att…

初识单点登录及JWT实现

单点登录 多系统&#xff0c;单一位置登录&#xff0c;实现多系统同时登录的一种技术 &#xff08;三方登录&#xff1a;某系统使用其他系统的用户&#xff0c;实现本系统登录的方式。如微信登录、支付宝登录&#xff09; 单点登录一般是用于互相授信的系统&#xff0c;实现单一…

Vue组件通信原理剖析(三)provide/inject原理分析

首先我们先从一个面试题入手。 面试官问&#xff1a; “Vue中组件通信的常用方式有哪些&#xff1f;” 我答&#xff1a; 1. props 2. 自定义事件 3. eventbus 4. vuex 5. 还有常见的边界情况$parent、$children、$root、$refs、provide/inject 6. 此外还有一些非props特性$att…

iMX6开发板-uboot-网络设置和测试

本文章基于迅为IMX6开发板 将iMX6开发板通过网线连接到路由器&#xff0c;同时连接好调试串口&#xff0c;上电立即按 enter&#xff0c;即可进入 uboot。然后输入命令 pri&#xff0c;查看开发板当前的配置&#xff0c;如下图所示可以看到 ip 地址、子网掩码 等信息。 本文档测…

Django ajax 检测用户名是否已被注册

添加一个 register.html 页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <form><p>用户名<input id"username" type&…

详解JDBC连接数据库

一、概念 1. 为了能让程序操作数据库&#xff0c;对数据库中的表进行操作&#xff0c;每一种数据库都会提供一套连接和操作该数据库的驱动&#xff0c;而且每种数据库的驱动都各不相同&#xff0c;例如mysql数据库使用mysql驱动&#xff0c;oracle数据库使用oracle驱动&#xf…

ZOJ4024 Peak

题意 给出一个数组 判断这个数组是否形成了一个“山峰” 即中间有个数最大 从第一个数到这个数递增 从这个数到最后一个数递减 模拟 从两端分别以递增和递减判断 看第一个不满足递增或递减的数是否相等并且没越界就可以了 AC代码&#xff1a; 1 #include<bits/stdc.h>2 u…

springmvc跨域问题

1、跨域问题&#xff1a; 按照网上所有的方法试了一遍&#xff0c;都没跨过去&#xff0c;正在无助之际&#xff0c;使用filter按照下面的方法解决的时候出现了转机&#xff1a; 添加filter&#xff1a; package com.thc.bpm.filter;import javax.servlet.*; import javax.serv…