jsp部分
enctype 属性是规定在发送到服务器之前应该如何对表单数据进行编码。
enctype常用的属性值有3个:第一个是application/x-www-form-urlencoded,这是默认的编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式,第二种是multipart/form-data,这种编码方式的表单会以二进制流的方式来处理表单数据,同时,这种编码方式也会把文件域指定文件的内容封装到请求参数里,第三种就是text/plain,这种方式主要适合用于直接通过表单发送邮件的方式。
上传文件的表单必须设置 enctype 为 multipart/form-data 类型(让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传)且method只能为post,不能为get。如果想要多文件上传,可以给文本域添加 multiple=”multiple” 属性。
如果想限制用户可以选择文件的格式,只需要添加 accept=”image/gif,image/png” 即可。
<form method="post" enctype="multipart/form-data">
<input type="file" name="upload_media" class="upload_media" multiple="multiple" />
<button type="submit">上传文件</button>
</form>
我们可以给文本域绑定一个事件,当其值发生改变的时候,我们验证用户选择的文件是否合法。
$(function(){
$('.upload_media').change(function(){
var files = $(this)[0].files;
for(var i = 0, f; f = files[i]; i++){
if(f.type == 'image/png' || f.type == 'image/gif' || f.type == 'image/jpg' || f.type == 'image/jpeg'){
if(f.size < 2*1024*1024){
//如果需要自动提交表单,可以使用下面的这行代码,否者就等到用户点击按钮再上传文件
//$('.upload_media').parent().submit();
}else{
alert(f.name + '文件超出上传大小限制!');
}
}else{
alert(f.name + '不是图片!');
}
})
})
以上内容出自-在web网页中开发上传文件功能,里面还有ajax上传文件的内容,有兴趣的话可以看一下。
关于以上代码的理解:
——${}是什么意思?
一般来说,$
是jQuery的别名,但是$()
根据括号里传入的参数不同,执行的内容完全不同。
例如:
var $ = function(id){
return document.getElementById(id);
}
那么运行$(id) 就等于运行了document.getElementById(id)
$()
的具体用法可以看:jQuery中$()函数的用法小结
这里就只介绍上文代码中的用法。
$('.upload_media').change()
:这里的.upload_media是css选择器,对应input type=”file” 中的class=”upload_media”,一旦选择了文件,就会触发change这个事件,里面的代码将会监听change事件。$(this)
是被jquery包着的input元素,$(this)[0]
就是input元素,后面的for就是在遍历多个文件了。
而第一个$()是以下这种用法:
通常JavaScript需要在DOM加载完成后执行,否则DOM操作可能会失效。jQuery提供了一个方便的方法来监听DOM加载完成
// 方法声明
jQuery( callback )
// 例子
$(function(){
// DOM载入后执行
});
$(callback)
的作用完全相当于$(document).ready(callback)
解释一下上面这段文字:浏览器是从上往下解析整个页面的,如果现在有一个场景:
<script>document.getElementById('A').value = '123'</script>
<input id="A"/>
这个js在这个input上面,那么会先解析js,去获取那个节点,,但是节点在下面还没生成呢,于是就报错了。为了解决这个问题,就需要在dom加载完成后再做相应的获取dom操作,这就是$.ready的目的。(这样它就可以放在代码的任意位置不出现问题)
当然,要先用js标签引入jQuery,不然会认不出$
注:必须要用 <script src="..."></script>
的形式引入jQuery,而不能用<script src="..."/>
的形式引入jQuery
引入jQuery:
1.引用在线jQuery
谷歌、微软、百度都有提供在线的jQuery引用。比如
<script src="http://code.jquery.com/jquery-latest.js"></script>
2.引用本地的jQuery。
先在下载jQuery.js文件或者jQuery.min.js文件(这个是压缩版的),放在项目中。
假如jQuery文件和当前js、html文件位于同一目录下,可以直接写jQuery的文件名。比如
<script src="jquery-3.2.1.min.js"></script>
如果jQuery文件和当前的js、html文件不是位于同一目录下,可以通过 .. 先返回上一层目录再引入jQuery。比如:
<script src="../jquery-3.2.1.min.js"></script>
另外,如果你使用的是Intellij Idea或者WebStrom等,可以直接将jQuery文件拖拉进当前代码中,会自动生成相关路径。
servlet部分
以下代码来自用jsp+servlet实现文件的上传与下载
package com.dw.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public UploadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");//更改响应字符流使用的编码,还能告知浏览器用什么编码进行显示
//从request中获取文本输入流信息
InputStream fileSourceStream = request.getInputStream();
String tempFileName = "F:/tempFile";
//设置临时文件,保存待上传的文本输入流
File tempFile = new File(tempFileName);
//outputStram文件输出流指向这个tempFile
FileOutputStream outputStream = new FileOutputStream(tempFile);
//读取文件流
byte temp[] = new byte[1024];
int n;
while(( n = fileSourceStream.read(temp)) != -1){
outputStream.write(temp, 0, n);
}
outputStream.close();
fileSourceStream.close();
//获取上传文件的名称
RandomAccessFile randomFile = new RandomAccessFile(tempFile,"r");
randomFile.readLine();
String str = randomFile.readLine();
int start = str.lastIndexOf("=") + 2;
int end = str.lastIndexOf("\"");
String filename = str.substring(start, end);
//定位文件指针到文件头
randomFile.seek(0);
long startIndex = 0;
int i = 1;
//获取文件内容的开始位置
while(( n = randomFile.readByte()) != -1 && i <=4){
if(n == '\n'){
startIndex = randomFile.getFilePointer();
i ++;
}
}
startIndex = startIndex -1; //这里一定要减1,因为前面多读了一个,这里很容易忽略
//获取文件内容结束位置
randomFile.seek(randomFile.length());
long endIndex = randomFile.getFilePointer();
int j = 1;
while(endIndex >=0 && j<=2){
endIndex--;
randomFile.seek(endIndex);
if(randomFile.readByte() == '\n'){
j++;
}
}
//设置保存上传文件的路径
String realPath = "F:/file";
File fileupload = new File(realPath);
if(!fileupload.exists()){
fileupload.mkdir();
}
File saveFile = new File(realPath,filename);
RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,"rw");
//根据起止位置从临时文件中读取文件内容
randomFile.seek(startIndex);
while(startIndex < endIndex){
randomAccessFile.write(randomFile.readByte());
startIndex = randomFile.getFilePointer();
}
//关闭输入输出流并 删除临时文件
randomAccessFile.close();
randomFile.close();
tempFile.delete();
request.setAttribute("result", "文件上传成功");
RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp");
dispatcher.forward(request, response);
}
}
以下内容来自菜鸟教程-jsp文件上传
以下是 UploadServlet 的源代码,同于处理文件上传,在这之前我们先确保依赖包已经引入到项目的 WEB-INF/lib 目录下:
下面的实例依赖于 FileUpload,所以一定要确保在您的 classpath 中有最新版本的 commons-fileupload.x.x.jar 文件。可以从 http://commons.apache.org/proper/commons-fileupload/ 下载。
FileUpload 依赖于 Commons IO,所以一定要确保在您的 classpath 中有最新版本的 commons-io-x.x.jar 文件。可以从 http://commons.apache.org/proper/commons-io/ 下载。
package com.runoob.test;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* Servlet implementation class UploadServlet
*/
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 上传文件存储目录
private static final String UPLOAD_DIRECTORY = "upload";
// 上传配置
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
/**
* 上传数据及保存文件
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 检测是否为多媒体上传
if (!ServletFileUpload.isMultipartContent(request)) {
// 如果不是则停止
PrintWriter writer = response.getWriter();
writer.println("Error: 表单必须包含 enctype=multipart/form-data");
writer.flush();
return;
}
// 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 设置临时存储目录
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);
// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);
// 中文处理
upload.setHeaderEncoding("UTF-8");
// 构造临时路径来存储上传的文件
// 这个路径相对当前应用的目录
String uploadPath = getServletContext().getRealPath("/") + File.separator + UPLOAD_DIRECTORY;
// 如果目录不存在则创建
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
try {
// 解析请求的内容提取文件数据
@SuppressWarnings("unchecked")
List<FileItem> formItems = upload.parseRequest(request);
if (formItems != null && formItems.size() > 0) {
// 迭代表单数据
for (FileItem item : formItems) {
// 处理不在表单中的字段
if (!item.isFormField()) {
String fileName = new File(item.getName()).getName();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
// 在控制台输出文件的上传路径
System.out.println(filePath);
// 保存文件到硬盘
item.write(storeFile);
request.setAttribute("message",
"文件上传成功!");
}
}
}
} catch (Exception ex) {
request.setAttribute("message",
"错误信息: " + ex.getMessage());
}
// 跳转到 message.jsp
getServletContext().getRequestDispatcher("/message.jsp").forward(
request, response);
}