【Servlet】利用Servlet3.0标准与JSTL表达式实现文件上传系统,支持图片上传后显示

伴随着JDK1.6一起出现的Servlet3.0标准,使得JSP的文件上传系统不再艰难,此前在JSP的文件上传系统需要《【Jsp】使用jspsmartupload完成简单的文件上传系统》(点击打开链接)类似这样的插件才能完成的文件上传系统,还不支持中文,使得各位程序猿掏空心思才能解决这个问题。现在Servlet3.0对文件上传的方法进行封装,无须分块就可以实现。而且Servlet3.0还不用类似《【Servlet】最简单的Servlet
JavaWeb程序》(点击打开链接)在web.xml里面各种配置,一个小小的Annotation就能完成以前在.xml的多行代码。

一、基本目标

实现如下的一个文件上传系统,上传之后显示文件类型、文件大小、文件名、文件后缀名,如果上传的是图片,则显示,无比健壮。大概唯一的缺点就是没有进度条……上传进度条也是一个大工程,以后再搞。而且编写出来的JSP页面符合Model2标准,在上传页面与上传成功显示页面,没有任何JSP代码,仅有JSTL表达式与JSP2.0自身的取值表达式。如果不想跳转可以参考《【Jsp】使用AjaxFileUploader与jspsmartupload完成不刷新的Ajax文件上传系统》(点击打开链接)的内容。

如果你直接访问我的上传文件Servlet,弹出提示。

上传完,文件保存在服务器上的/upload文件夹里面,服务器一般不存中文文件名的,每一个文件名是时间戳,多用户上传还可以加上取走用户的ID并接文件名,时间戳的生成可以看我之前写的《【Java】有关System.currentTimeMillis()的思考》(点击打开链接

二、基本准备

这个利用Servlet3.0标准与JSTL表达式实现上传系统的WEB工程目录结构如下所示:

首先在WebContent,如果是Myeclipse则是WebRoot网站根目录文件夹,下面新建一个upload文件夹,用来摆上传文件的。

web.xml文件则如《【Javaweb】Eclipse for JavaEE新建的Web工程自动生成web.xml》(点击打开链接)让Eclipse自己建可以,里面不用写任何东西了。精简之后如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
</web-app>

然后再lib文件夹下面放入Servlet3.0的支持包javax.servlet-api-3.1.0.jar,JSTL表达式的支持包jstl.jar与standard.jar,这些东西都是JSP官方自己开发的东西和Tomcat一样,高版本的Tomcat还会自带,但是为了兼容所有版本的Tomcat还是要放的。这些东西自己上网搜一下就可以了。JSTL表达式的支持包jstl.jar与standard.jar要去搜索jakarta-taglibs-standard-1.1.2.zip,下载之后解压如下图所示,把lib里面的东西都取走。

三、制作过程

1、首先是最简单,只要学过HTML都会的Fileupload.jsp,就一个带文件表单,注意其中的写法,当时讲解前端的时候,文件表单或许提到过一下,注意除了post与action属性,还有enctype="multipart/form-data",表明这是传递文件的,文件表单必须配合服务器语言aspx,jsp,php三者之一,跑在服务器上面才有效的:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>FileUpload</title>
</head>
<body>
	<form method="post" action="upload" enctype="multipart/form-data">
		选择文件:<input type="file" name="file" /><br />
		<input type="submit" value="上传" />
	</form>
</body>
</html>

2、之后是Upload.java,来到了Servlet3.0,就再也不用搞web.xml了,可以利用Part对象接住整个上传过来的文件,加一句response.setCharacterEncoding("utf-8");解码就能支持中文了,如果利用拦截器实现全局解码,那么这句话也可以省了,可以参考我之前的《【Filter】利用过滤器Filter解决post传递的编码问题与利用EL表达式简化参数传递》(点击打开链接),剩下只是切割字符串的问题了,另外设置一个动态数组arraylist配合后面的JSTL表达式的,动态数组arraylist不懂可以看《【Java】Java中的Collections类——Java中升级版的数据结构》(点击打开链接),同时保存服务器的文件名是时间戳,一切内容的传递利用request容器,这容器请求之后就消息,也就是说request容器跳转前出生,跳转完毕页面加载完,request容器就立即死亡,具体看注释。

//有文件就有IO,util是设置一个arraylist配合后面的JSTL表达式的
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
//这样设置就可以取代以前的web.xml配置Servlet的方式,但要注意引入Annotation包
@WebServlet(name="upload",urlPatterns={"/upload"})
//这是一个处理文件的Servlet
@MultipartConfig
public class Upload extends HttpServlet {
	// 防止用户直接输入网址访问此Servlet
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		out.print("请正常打开此页");
	}

	//文件一般用doPost方法
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		//解码
		response.setCharacterEncoding("utf-8");
		//把name为file的<input type="file" name="file" />里面选择的文件传递过来
		Part part=request.getPart("file");
		//这样就能够取到上传文件名,不为什么,
		//content-disposition前面35个字符是form-data文件表单名name="file"
		//每一个上传的文件都是固定的
		String filename=part.getHeaders("content-disposition").toString().substring(35).replace("\"]", "");
		//对文件名从.开始截取就能取到文件的后缀名
		String fileExtensions=filename.substring(filename.lastIndexOf("."));
		//设置一个动态数组FileInfo,不停把文件信息放进去
		ArrayList<String> FileInfo=new ArrayList<String>();
		FileInfo.add("文件类型:"+part.getContentType());
		FileInfo.add("文件大小:"+part.getSize()/1024+"kb");
		FileInfo.add("文件名:"+filename);
		FileInfo.add("后缀名:"+fileExtensions);
		//为文件的后缀名独立设置一个参数
		request.setAttribute("fileExtensions",fileExtensions);
		//这个是服务器上面的文件名,利用System.currentTimeMillis()时间戳
		//后面补个+""就能把long强制toString()了
		String ServersFilename=System.currentTimeMillis()+"";
		//动态数组FileInfo同时也保存这个在服务器的名字
		//用于后续组成图片显示的地址
		FileInfo.add(ServersFilename);
		//之后,把动态数组FileInfo放进容器
		request.setAttribute("FileInfo",FileInfo);
		//如果文件名是以图片后缀名结尾的
		//当然你也可以里面上面的fileExtensions用equal方法来判断
		//记得字符串是对象,千万不要用==去比较就可以了
		if(filename.endsWith(".jpg")||filename.endsWith(".gif")||filename.endsWith(".bmp")||filename.endsWith(".png")){
			//在于request设置一个属性hasPic,告诉下一页是否图片
			request.setAttribute("hasPic","true");
		}
		else{
			request.setAttribute("hasPic","false");
		}
		//把文件保存到服务器getServletContext().getRealPath("/upload")能取到服务器/upload的目录
		//不带参数则是根目录
		//之后就是保存到服务器的名字与文件的后缀名并接起来就可以了
		part.write(getServletContext().getRealPath("/upload")+"/"+ServersFilename+fileExtensions);
		//之后带着request容器跳转到UploadSuccess页面
		request.getRequestDispatcher("/UploadSuccess.jsp").forward(request,response);
	}
}

还有一点补充的是:part.getSize()方法取出来的文件大小是以bit为单位,请自己除以1024,或者1024的平方去换算。

3、上传成功显示页面UploadSuccess.jsp,这一页还肩负着显示图片的任务,同时使用到了JSTL表达式,记得在本页头部声明要是用C标签,具体如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!-- 表明我要使用JSTL表达式! -->
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Success</title>
</head>
<body>
<%-- <c:choose>表示一个条件结构配合<c:when>与<c:otherwise>相当于if..else结构 --%>
	<c:choose>
	<!-- 先判断hasPic是否是true,用户是不是上传了一张图片? -->
		<c:when test="${requestScope.hasPic=='true'}">
		<%-- <c:forEach>就是循环结构 --%>
		<!-- 遍历request容器里面的动态数组FileInfo,其中每一项的以fileinfo表示 -->
		<!-- 类似php的foreach与Jdk1.5的新型遍历 -->
		<!-- fileinfoStatus旗下有很多类成员用来判断状态的 -->
			<c:forEach var="fileinfo" items="${requestScope.FileInfo}"
				varStatus="fileinfoStatus">
				<c:choose>
					<!-- 因为动态数组FileInfo的最后一项正是服务器上面的图片的文件名! -->
					<c:when test="${fileinfoStatus.last}">
						<!-- 因此如果遍历到这一项,就upload/+服务器上面的图片的文件名+文件的后缀名并接其一个图片地址,用img标签显示 -->
						<img src="upload/<c:out value="${fileinfo}" /><c:out value="${requestScope.fileExtensions}" />" />
					</c:when>
					<c:otherwise>
						<!-- 不然就逐一输出文件信息咯! -->
						<c:out value="${fileinfo}" />
						<br />
					</c:otherwise>
				</c:choose>
			</c:forEach>
		</c:when>
		<!-- 如果不是图片 -->
		<c:otherwise>
			<!-- 那么就显示动态数组FileInfo中的0-3项,逐一显示 -->
			<!-- 其实不写,也是默认显示整个数组,主要是为了说明begin,end,step等各个参数 -->
			<!-- step的意思就是逐X个显示,每X次显示一次的意思 -->
			<c:forEach var="fileinfo" items="${requestScope.FileInfo}" begin="0"
				end="3" step="1">
				<c:out value="${fileinfo}" />
				<br />
			</c:forEach>
		</c:otherwise>
	</c:choose>
</body>
</html>

做到这里,整个利用Servlet3.0标准与JSTL表达式,支持图片上传后显示的文件上传系统,就做完了。

各位体现到Servlet3.0标准与JSTL表达式的Model 2的标准的优越性了吗?

当然又有各种SSH大神准备喷我了……

时间: 2024-10-05 18:18:45

【Servlet】利用Servlet3.0标准与JSTL表达式实现文件上传系统,支持图片上传后显示的相关文章

注解方式配置Servlet(Servlet3.0)

注解方式配置Servlet(Servlet3.0) Servlet3.0 主页http://download.oracle.com/otndocs/jcp/servlet-3.0-fr-eval-oth-JSpec/ 1.简单的servlet配置 @WebServlet(”/myservlet”) @WebServlet(name=”MyServlet”, urlPatterns={"/myservlet", "/bar"}) xxx/myservlet就可用执行该

html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器

原文:html5 图片上传,支持图片预览.压缩.及进度显示,兼容IE6+及标准浏览器 以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一般的上传没有问题,不过如果是上传图片,且需要预览的话,就力有不逮了,趁着闲暇时间,给上传组件添加了单独的图片上传UI,支持图片预览和缩放(通过调整图片的大小以实现图片压缩). 上传组件特点 轻量级,不依赖任何JS库,核心代码(Q.Uploader.js)仅约700行,min版本加起来不到12KB 纯

【Servlet】Servlet3.0与纯javascript通过Ajax交互

这是一个老生常谈的问题,对于很多人来说应该很简单.不过还是写写,方便Ajax学习的后来者.虽然js.html是一个纯静态的页面,但是以下的程序必须挂在Tomcat服务器上,才能做到Ajax交互,否则看不出效果的.Eclipse for javaee注意把做好的工程挂在Tomcat上,才运行Tomcat.本工程除了JSP必须的Servlet包以外,无须引入其它东西.其实想直接用一个JSP页面完成这个工程的,但是现在搞JSP的,基本上没有人直接在.jsp文件中写东西了吧?后台动作都扔到.java里面

利用servlet3.0上传,纯原生上传,不依赖任何第三方包

tomcat7里面自带的servlet3.0.jar,支持很多新特性,例如,annotation配置servlet,上传,异步等等.... 如果你的tomcat版本低于7的话,单独在项目中引入servlet3.0.jar的话,有可能会出错,具体没研究过,可能是不兼容吧.所以要使用servlet3.0新特性的话,尽量使用tomcat7 不多说了,贴上代码 @WebServlet(name = "uploadServlet", urlPatterns = "/uploadServ

使用servlet3.0提供的API来进行文件的上传操作

servlet 3.0针对文件上传做了一些优化,提供了一些更加人性化的API可以直接在request中的到文件的名称.文件size,MIME类型,以及用InputStream表示的文件流的信息 @RequestMapping(value = "/add", method = RequestMethod.POST) @ResponseBody public String addFile(HttpServletRequest request) throws IOException, Ser

Servlet3.0学习总结(一)——使用注解标注Servlet

一.Servlet3.0介绍 Servlet3.0是Java EE6规范的一部分,Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述,简化开发流程. 二.开发Servlet3.0程序的所需要的环境 开发Servlet3.0的程序需要一定的环境支持.MyEclipse10和Tomcat7都提供了对Java EE6规范的支持.Tomcat需要Tomcat7才支持Java EE6,Tomcat7需要使用JDK1.6以上的版本. 所以开

项目支持Servlet3.0的新特性

一.Servlet3.0介绍 Servlet3.0是Java EE6规范的一部分,Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述,简化开发流程. 二.开发Servlet3.0程序的所需要的环境 开发Servlet3.0的程序需要一定的环境支持.MyEclipse10和Tomcat7都提供了对Java EE6规范的支持.Tomcat需要Tomcat7才支持Java EE6,Tomcat7需要使用JDK1.6以上的版本. 所以开

基于Servlet3.0+IBatis+BootStrip技术构建简单会议管理系统

网盘地址:https://pan.baidu.com/s/1i65cPSD 密码: 63ia网盘地址:https://pan.baidu.com/s/1kXmqkM7 密码: v4ry 本系统是应用于企业会议管理的系统,实现自动管理会议室,及时准确得知会议室空闲.预定情况,规范公司会议管理,实现公司信息资源在各部门之间快速有效传递,避免资源的冲突.提高了会议室的使用率,节省会议组织者的时间,妥善保管了会议记录. 学习目标本系列讲座主要讲述如何利用Servlet3.0+mybatis+bootst

java web学习总结(二十一) -------------------模拟Servlet3.0使用注解的方式配置Servlet

一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet-name>ActionServlet</servlet-name> 3 <servlet-class>me.gacl.web.controller.ActionServlet</servlet-class> 4 </servlet> 5 6 <ser