您的位置:首页 > 编程语言 > Java开发

小博老师解析Java核心技术点

2016-11-11 09:48 211 查看
[理论知识]

我们在软件开发工作中,会经常遇到需要用户上传文件的情况,比如上传头像、上传商品图片等等。首先我们要了解文件上传的技术原理,上传文件并非是将文件直接从客户端传送到服务器端,网络中传递的数据都是基于字符的,客户端首先将用户选择的文件中的字符读取出来,将字符传递给服务器,服务器再将收到的字符写入到服务器中的指定文件,以这样的方式实现了文件的上传功能。

因此我们知道,上传文件一般使用POST方式,因为GET方式传输数据有大小限制,另外上传数据的编码格式需要使用multipart/form-data,不能使用form表单默认的application/x-www-form-urlencoded。

[步骤解读一]上传文件的POST报文

本文中,小博老师将为大家演示如何实现文件上传的功能。首先我们创建一个jsp文件,提供上传文件的表单,核心代码如下:

<form action="BWFUpload" method="POST" enctype="multipart/form-data">

用户名称:<input type="text" name="nickName"/><br/><br/>

上传图片:<input type="file" name="upload"/><br/><br/>

<input type="submit" value="开始上传"/>

</form>

我们看到form表单的enctype属性,这个属性时encoding type的缩写,表示表单中数据提交时的编码格式,这个属性的值我们必须要修改成multipart/form-data才能实现文件上传的功能,但是此属性一旦修改,就会改变我们获取表单提交数据的方式,比如我们创建Servlet先来获取文本框中的提交数据:

@WebServlet("/BWFUpload")

public class BWFUploadServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

response.setHeader("Content-Type", "text/html; charset=UTF-8");

PrintWriter out = response.getWriter();

String nickName = request.getParameter("nickName");

out.println( nickName );

}

}

通过浏览器我们提交文本框数据,会发现我们再使用request.getParameter(String key)的方式,已经无法获取表单提交的数据了:






 

form表单的enctype属性值修改为multipart/form-data后,form表单就不会对控件中数据进行编码了,而是将整个form表单中的数据,生成post报文提交给服务器。我们修改Servlet中的代码,输出post报文给大家看一下,核心代码如下:

@WebServlet("/BWFUpload")

public class BWFUploadServlet extends HttpServlet {

 

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

response.setHeader("Content-Type", "text/html; charset=UTF-8");

PrintWriter out = response.getWriter();

// 通过request对象创建输入字节流

InputStream is = request.getInputStream();

// 准备StringBuilder拼接post报文

StringBuilder builder = new StringBuilder();

int i;
// 准备int变量,获取每次读取到的字节

// 循环从字节输入流中读取数据

while( ( i = is.read() ) != -1 ){

builder.append( (char)i );

}

is.close();
// 关闭流

// 输出post报文

out.println(builder.toString());

}

}

我们通过浏览器访问jsp页面,在表单中填写文本信息和上传文件:


 

提交表单给Servlet后,post报文如下:


 

仔细观察post报文,我们会发现其中包含了我们上传的文本信息,以及上传文件的基础信息(name="upload"; filename="bwf_logo.png" Content-Type: image/png ‰PNG),以及上传的文件的内容(内容过大,这里不复制了),在这样的情况下,如果我们需要自己从post报文中截取需要的信息,开发效率会非常低下,小博老师强烈建议使用现成的第三方插件来完成后续任务。

[步骤解读二]JspSmartUpload插件使用

我们可以在网上下载一个第三方插件-JspSmartUpload,将jar文件放入项目lib文件夹中即可。我们修改Servlet,使用JspSmartUpload插件先获取文本框中信息,核心代码如下:

@WebServlet("/BWFUpload")

public class BWFUploadServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

response.setHeader("Content-Type", "text/html; charset=UTF-8");

PrintWriter out = response.getWriter();

// 实例化 SmartUpload 对象

SmartUpload upload = new SmartUpload();

// 初始化参数

upload.initialize(getServletConfig(), request, response);

try{

// 解读post报文,将上传文件生成临时文件,其他普通参数封装成map

upload.upload();

// 将解读post报文后拆分的数据,重新封装成SmartUpload包中的Request对象

// 注意此处的Request对象是com.jspsmart.upload.Request而非HttpServletRequest

// 但是两者的使用方法基本一致

Request req = upload.getRequest();

// 从 新封装的 Request对象中获取文本信息

String nickName = req.getParameter("nickName");

out.println(nickName);

}catch(Exception e){

e.printStackTrace();

}

}

}

用浏览器访问jsp页面,在表单中填写文本信息提交:


 

提交给Servlet后,文本信息获取成功:


 

[步骤解读三]JspSmartUpload插件实现文件上传

接下来,我们修改Servlet中的代码,实现文件上传功能,核心代码如下:

@WebServlet("/BWFUpload")

public class BWFUploadServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

response.setHeader("Content-Type", "text/html; charset=UTF-8");

PrintWriter out = response.getWriter();

// 实例化 SmartUpload 对象

SmartUpload upload = new SmartUpload();

// 初始化参数

upload.initialize(getServletConfig(), request, response);

try{

// 解读post报文,将上传文件生成临时文件,其他普通参数封装成map

upload.upload();

// 获取所有上传文件在服务器存放的临时文件

Files files = upload.getFiles();

// 循环每一个临时文件

forint i = 0 ; i <= files.getCount()
- 1; i++ ){

// 获取当前循环到的临时文件

File file = files.getFile(i);

// 为文件生成新的文件名

String filename = UUID.randomUUID().toString()+file.getFileName().substring( file.getFileName().lastIndexOf(".")
);

// 将当前内循环到的临时文件 另存到指定目标位置

file.saveAs( getServletContext().getRealPath( "uploads/"+filename ) );

}

}catch(Exception e){

e.printStackTrace();

}

}

}

上传文件功能实现:


 


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息