前言
这里是javaweb小白第一次尝试写博客,主要是想记录一下自己在学习JavaWeb的成长历程、记录在编写程序时解决的一些问题。也想借此帮助自己对知识点的消化和对代码结构体系上的深入理解,如果能帮助到同样正在学习这部分内容的小伙伴,那是莫大的荣幸!
回到正题,该篇讲解的是一个利用Servlet处理页面上传的JSON文件,对其解析后以表格形式呈现在响应页面,并可勾选相应的行下载导出excel文件。
一、实例要求
二、主要问题点
1.保存请求中的文件
首先我们要了解文件在http请求消息中的格式
我们通过表单向服务器发送包含了用户在浏览器页面上传的文件的http请求
<form enctype="multipart/form-data" method="post" action="fileUpload.do">
<table border="1px">
<tr>
<td colspan="2" style="text-align: center">文件上传</td>
</tr>
<tr>
<td>会员号:</td>
<td><input type="text" name="mnumber" size="30"></td>
</tr>
<tr>
<td>文件名:</td>
<td><input type="file" name="fname" size="30"></td>
</tr>
<tr>
<td style="text-align: right"><input type="submit" value="提交"></td>
<td style="text-align: left"><input type="reset" value="重置"></td>
</tr>
</table>
</form>
在form标签内 定义了编码类型enctype="multipart/form-data"
,并以POST方法发送请求。
关于enctype
属性,在POST请求方法下默认为application/x-www-form-urlencoded
,在这种编码格式下,数据会被编码成以被&
分隔的健-值对的形式,健-对值之间以=
分隔,也就是key=value
另一种text/plain
纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。这里不做过多介绍。
还有一种编码方式就是例中所用的multipart/form-data
指定传输数据为二进制类型,比如图片、mp3、文件。表明表单数据为复合类型数据,包含多个子部分,这种方式提交的表单在我们的数据分离后,会以boundary
开头、last boundary
结尾。其中每个部分的描述都有HTTP头部描述子包体,如Content-type
我们使用wireshark抓取这个请求消息进一步解析
看到请求头Content-Type正文类型为multipart/form-data,对应了form标签内定义的编码类型。
表单的包体在http报文的正文内容,使用MIME多功能网际邮件拓展协议
图中第三行First boundary
开始为第一个子包体,name="mnumber"
,是<input type="text" name="mnumber" size="30">
对应的请求参数名,该子包体以Boundary
为标志结束
第二个part是请求中JSON文件,Content-Type:application/json
表示了这个资源的类型,name="fname"
是该资源的请求参数名,之后的代码中我们就会借助这个参数名来获取这个part,filename="javascore.json"
是资源文件名
报文最后以Last boundary
来结尾表明所有的资源文件都传输完毕。
由此条抓取的报文印证了multipart/form-data
方式,复合型、多个部分、以boundary
边界分隔的结构特征,能帮助我们从代码层面对请求包资源的操作理解。
String mNumber=request.getParameter("mnumber");
//获取上传的文件、request.getPart(“属性名”)用于获取使用multipart/form-data格式传递的http请求的请求体,通常用于获取上传文件。
//part.getSubmittedFileName();拿到文件名
Part part= request.getPart("fname");
//将上传的文件内容写入服务器文件中
part.write(fileSavingPath);
附上相应的代码语句,是不是就能更好地理解这些方法的含义
对于保存上传的文件到服务器,本例中采取了指定绝对路径的做法,这样做的缺点是只适用于一台服务器,不好做迁移。更好的解决办法是获取web项目在硬盘的绝对路径,再保存文件到web应用根目录的相对路径上。
为此我们可以使用servlet中用ServlertContext
域的getRealPath()
这个方法来动态的获取web应用的绝对路径(关于ServlertContext
域将在后文介绍)
//参数"/"获取web应用输出根目录
String fileSavingFolder = this.getServletContext().getRealPath("/");
此方法有时候会遇到获取的路径在target文件夹下,这时需要更改tomcat服务器项目部署的输出目录至webapp文件夹下
2.JSON的简单处理
简单介绍一下JSON的格式
JSON三种格式:
(一)简单值:数字、字符串、布尔值
(二)对象形式:
(三)数组形式
本例中的测试案例:
使用FastJson对JSON解析,当然也可以以字符串类型手动解析,只是比较繁琐。
FastJson环境配置非常简单,只需在pom.xml文件中加入以下依赖项,重新加载maven即可
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
解析的思路:先读取文件内容到字符串数组再使用JSON.parseArray()
转化为JSON数组,逐个取出对象进行解析
代码如下(示例):
//获取存储在请求对象中的文件路径
String filePath=String.valueOf(request.getAttribute("fileSavingPath"