博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Servlet(Request.Response)+文件上传
阅读量:6954 次
发布时间:2019-06-27

本文共 20035 字,大约阅读时间需要 66 分钟。

hot3.png

 

1. Servlet简介

1.1. 什么是Servlet

(1) servlet是运行在Web服务器中的小型Java程序。 

(2) servlet通常通过HTTP(超文本传输协议)接收和响应来自Web客户端的请求。

1.2. 实现Servlet

(1) 实现Servlet接口 

如果实现接口,需要把接口里面的方法都实现。 
(2) 继承GenericServlet, HttpServlet类 
如果继承类,不需要把类中的方法都实现。 
(3) 需要web服务器知道Java程序不是一个普通的java程序,而是一个servlet 
通过配置进行操作,在web项目中,web.xml里面进行配置。

1.3. Servlet的入门程序

写一个servlet,实现向页面输出内容hello servlet 

第一步,创建一个类,使用这个类继承GenericServlet类; 
第二步,实现类里面的service(ServletRequest req,ServletResponse res); 
       * ServletRequest代表请求 
       * ServletResponse代表响应 
第三步,在Servlet中使用ServletResponse对象向页面输出内容。调用getWriter()方法; 
第四步,在web项目中的web.xml进行配置,让服务器知道是一个servlet

servletDemo1
com.gaogao.servlet.ServletDemo1
servletDemo1
/hello

2. Servlet的执行过程

(1) 根据在浏览器地址栏输入的地址,找web.xml中相同的url-pattern; 

(2) 找到了url-pattern,对应的servlet-name; 
(3) 根据找到的servlet-name到另外一个标签里面(servlet)相同名称的servlet-name; 
(4) 在servlet标签里面找到了相同名称的servlet-name,找servlet的包类路径servlet-class; 
Servlet其实是利用反射原理,让servlet里面的service()方法执行。 
这里写图片描述

servlet的生命周期:从servlet创建到servlet销毁的过程。 

在servlet接口里面有五个方法,其中有三个方法是与生命周期相关的方法: 
(1) init()方法,在servlet创建时候执行这个方法,执行一次,servlet在第一次访问时候创建。 
(2) service()方法,在每次访问servlet时候会执行这个方法,执行多次。 
(3) destroy()方法,销毁servlet时候执行这个方法,执行一次。

4. Servlet开发细节的问题

4.1. HttpServletRequest和ServletRequest关系&HttpServletResponse和ServletResponse关系 

servletRequest和serlvetResponse不带协议 
HttpServletRequest和HttpServletResponse带协议 
sun公司设计时候,认为未来互联网的发展有很多的协议,目前只有http协议。

4.2. GenericServlet类两个init方法

查看源码,发现有参数init方法最终也要调用init没有参数的方法,直接使用init没有参数的方法就可以了。

4.3. HttpServlet类里service和doxxx关系

根据提交的方式,调用不同的doXX的方法,比如提交方式是get,调用doGet方法,比如提交方式是post,调用doPost方法; 

一般在开发中,直接写doGet和doPost方法就可以了; 
一般在创建servlet时候,直接继承HttpServlet实现servlet。

4.4. 服务器启动时候创建servlet

通过配置文件进行配置,在servlet标签里面写标签:

正整数的值
  •  

4.5. 简化编程

当通过get提交方式时候,实现从1加到100; 

当通过post提交方式时候,实现从1加到100; 
无论什么提交方式,代码都能执行到,在dopost方法里面调用doget方法。

5. url-pattern的配置

5.1. 配置有三种方式

第一种方式:完全路径匹配,写法 :/aa/hello 

第二种方式:目录匹配,写法:/aa/* 
第三种方式:扩展名匹配,写法: *.do, *.action

5.2. 优先级

完全路径匹配 > 目录匹配 > 扩展名匹配

5.3. 练习

对于如下的一些映射关系: 

Servlet1 映射到 /abc/* 
Servlet2 映射到/* 
Servlet3 映射到 /abc 
Servlet4 映射到 *.do 
问题: 
1、当请求URL为"/abc/a.html""/abc/*""/*"都匹配,哪个servlet响应? 
Servlet1 
2、当请求URL为"/abc"时,"/abc/*""/abc"都匹配,哪个servlet响应? 
Servlet3 
3、当请求URL为"/abc/a.do"时,"/abc/*""*.do"都匹配,哪个servlet响应? 
Servlet1 
4、当请求URL为"/a.do"时,"/*""*.do"都匹配,哪个servlet响应? 
Servlet2 
5、当请求URL为"/xxx/yyy/a.do"时,"/*""*.do"都匹配,哪个servlet响应? 
Servlet2

6. 开发中路径的问题

6.1. 相对路径

在html文件中引入图片: 

第一种:图片和html在同一个目录下面,直接写图片的名称 
第二种:图片在html的上层目录, 写 ../ 表示上层目录 
第三种:图片在html的下层目录, 直接写目录名称和图片名称

6.2. 绝对路径(一般开发中都使用)

第一种写法:http://ip地址+端口号/文件的路径 

<img src="http://127.0.0.1/day07-3/path02/a.jpg"/> 
第二种写法:直接写 /项目名称/文件路径 
<img src="/day07-3/path01/cc/c.jpg"/>

7. 请求重定向和请求转发

7.1. 请求重定向

(1) 使用的是客户端路径 

(2) 重定向请求两次,使用的是客户端路径,携带项目名称,比如/day07/demo3 
这里写图片描述 
请求重定向可以使用一下两种方式: 
a) 设置状态码302+头信息Location实现重定向操作 
b) 使用response.sendRedirect()实现重定向操作

public class LoginServlet extends HttpServlet {    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {        //得到输入的用户名和密码        String username = request.getParameter("username");        String password = request.getParameter("password");        //根据用户名和密码判断,(用户名admin、密码123456),判断正确则向页面输出login success内容        if("admin".equals(username) && "123456".equals(password)) {            //向页面输出内容            response.getWriter().write("login success");        } else {             //重定向到登录页面            //设置状态码//          response.setStatus(302);            //使用头Location完成重定向//          response.setHeader("Location", "/day08-1/login.html");            //简写方式            response.sendRedirect("/day08-1/login.html");        }    }    public void doPost(HttpServletRequest request,HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

定时跳转的案例

public class RefreshServlet extends HttpServlet {    /**     * 定时跳转     */    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {        //使用头信息Refresh实现,表示5秒后跳转到指定的url路径        response.setHeader("Refresh", "5;url=/day08-1/login.html");        //提示        response.setContentType("text/html;charset=utf-8");        response.getWriter().write("将在5秒之后跳转到登录页面");    }    public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {        doGet(request, response);    }}

7.2. 请求转发

(1) 使用的是服务端路径 

(2) 转发请求一次,使用的是服务器端路径,不需要携带项目名称,比如/demo4 
这里写图片描述 
示例代码:

public class LoginServlet extends HttpServlet {    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {        //获取表单提交的用户名和密码        String username = request.getParameter("username");        String password = request.getParameter("password");        //判断 用户名 admin,密码 123456        if("admin".equals(username) && "123456".equals(password)) {            //登录成功            response.getWriter().write("login success");        } else {            //登录失败,给request设置域属性msg,并且转发到登录页面,并且将错误信息传递过去            request.setAttribute("msg", "用户名或者密码错误");            request.getRequestDispatcher("/login.jsp").forward(request, response);        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {        doGet(request, response);    }}

8. ServletConfig对象

8.1. 获取ServletConfig对象

直接使用方法创建对象getServletConfig()。

8.2. 得到当前运行的servlet的名称

(1)web.xml中<servlet-name>ConfigDemo1</servlet-name> 

(2)String getServletName()

8.3. 创建servletContext对象

(1)ServletContext getServletContext() 

(2)一般都使用getServletContext()方法

8.4. 获取初始化参数

(1)在web.xml中进行配置初始化参数 

在servlet标签里面进行配置 
(2)String getInitParameter(String name) :根据名称得到值(参数是初始化参数名称) 
代码:

//得到servletconfig对象ServletConfig config = getServletConfig();//getInitParameter(String name)String username = config.getInitParameter("username");String password = config.getInitParameter("password");

(3)Enumeration getInitParameterNames() :得到所有的初始化参数的名称 

代码:

//得到servletconfig对象ServletConfig config = getServletConfig();//得到所有的初始化参数名称Enumeration
enumrEnumeration =config.getInitParameterNames();//得到每个参数的名称while(enumrEnumeration.hasMoreElements()) { String name = enumrEnumeration.nextElement(); //根据name得到值 String value = config.getInitParameter(name); System.out.println(name+" :: "+value);}

9. ServletContext对象

9.1. 创建ServletContext对象

第一种方式,使用ServletConfig对象里面的方法 getServletContext() 

第二种方式,直接使用 getServletContext()

9.2. 获取全局的初始化参数

(1)配置全局初始化参数

url
localhost

(2)String getInitParameter(String name),根据名称得到全局初始化参数的值:

//得到servletContext对象ServletContext context = getServletContext();//根据名称得到全局初始化参数的值String url = context.getInitParameter("url");String name = context.getInitParameter("name");

(3)Enumeration getInitParameterNames(),得到所有的全局初始化参数的名称:

//得到servletContext对象ServletContext context = getServletContext();//使用方法得到所有的全局初始化参数的名称Enumeration
enumrEnumeration = context.getInitParameterNames();//得到每个全局初始化参数的名称while(enumrEnumeration.hasMoreElements()) { String name = enumrEnumeration.nextElement(); String value = context.getInitParameter(name); System.out.println(name+" :: "+value);}

9.3. servletContext域对象

在启动tomcat服务器时候,会为每个项目创建一个servletContext对象,在这个项目里面如果通过servlet1向servletContext里面设置一个值,在这个项目里面的其他的servlet里面都可以获得这个值。 

(1)servletContext域对象:在一定的范围内,存值和取值,范围是整个web项目 
(2)存值:setAttribute(String name, Object object) 
(3)取值:getAttribute(String name) 
(4)首先创建servlet1,通过servlet1向servletContext里面设置一个值,其次,再创建servlet2,在servlet2获取通过servlet1设置的值

9.4. 练习:统计网站的访问次数

创建一个servlet,每次访问这个servlet计算一次访问 

实现的步骤(分析图) 
这里写图片描述

10. ServletContext获取项目资源

10.1. 传统方式获取web项目中的文件

(1)创建web项目,创建properties文件 

(2)得到要操作文件的输入流,使用相对路径 
       * classes/db1.properties : 相对路径 
       * 相对虚拟机的位置 
       * 在web项目中,虚拟机在tomcat启动时候,tomcat在bin里面 
(3)使用传统方式里面的相对路径,不能读取web项目中的文件

10.2. ServletContext读取项目中的文件

(1)InputStream getResourceAsStream(java.lang.String path),得到要操作文件的输入流 

(a)第一个操作:文件放到src下面 
路径:第一个位置/,理解为项目的名称;后面写文件在tomcat的webapps里面的具体的路径 
代码:

InputStream in = context.getResourceAsStream("/WEB-INF/classes/db1.properties");
  •  

(b)第二个操作:文件放到包里面 

路径:第一个位置/理解为项目名称;后面写文件在tomcat的webapps下面的具体的路径

InputStream in= context.getResourceAsStream("/WEB-INF/classes/cn/itcast/read/db2.properties");

(c)第三个操作:文件放到webroot下面 

路径:第一个位置/理解为项目名称;后面写文件在tomcat的webapps下面的具体的路径 
代码:

InputStream in = context.getResourceAsStream("/db3.properties");

*注意:当把文件放到和webroot同级的目录下面,这个文件不会部署到tomcat里面,所以使用servletContext对里面getResourceAsStream方法不能得到文件的内容。

(2)String getRealPath(java.lang.String path),得到要操作文件的完全路径(带盘符的路径) 

参数:和getResourceAsStream类似的 
第一个位置/,项目名称;后面写文件在tomcat的webapps里面的具体的路径。 
代码:

//使用getRealPath方法String path = context.getRealPath("/db3.properties");//C:\Users\asus\Desktop\javaweb\day06\apache-tomcat-7.0.53\webapps\day07-7\db3.properties//得到要操作文件的输入流InputStream in = new FileInputStream(path);

11. 类加载器读取文件

读取的文件的位置是 classes里面的文件 

得到类加载器: 
(1)首先得到Class 
       *第一种方式:类名.class 
       *第二种方式:对象.getClass() 
       *第三种方式:Class.forName(“包类路径”)

(2)使用Class得到类加载器 

代码:

//得到类的ClassClass clazz = ServletDemo1.class;//得到类加载器ClassLoader loader = clazz.getClassLoader();//得到要操作文件的输入流//文件的路径,因为读取的classes里面的文件,直接写文件的名称InputStream in = loader.getResourceAsStream("db1.properties");

12. 默认的servlet

比如在浏览器的地址栏随便输入一个地址,出现404,资源找不到,这个效果是由默认的servlet实现的。在tomcat的conf里面找到web.xml,有对默认servlet的配置: 

(a)如果自己创建servlet,让这个servlet在启动时候创建,<load-on-startup>大于1的值</load-on-startup> 
(b)默认servlet的配置里面url-pattern是/,当把自己创建的servlet的url-pattern写成/,这个servlet就会成为一个默认的servlet

default
org.apache.catalina.servlets.DefaultServlet
debug
0
listings
false
1
default
/

在默认的servlet的初始化参数里面有 listings,当把这个参数的值设置成true之后,当直接访问web项目中文件夹时候,会把文件夹里面的所有内容显示出来。

13. Response和Request

request:代表请求,在浏览器的地址栏输入地址,点击回车,这个过程称为一次请求; 

response:代表响应,服务器端根据客户端的请求,返回数据到浏览器中进行显示,这个过程称为一次响应。

14. Response对象

HttpServletResponse,是一个接口,父接口是ServletResponse,代表响应对象。 

http的响应包含三部分组成: 
(1)第一部分:响应行,响应行中包含了状态码 
常用方法:

方法 作用
setStatus(int sc) 设置状态码 如response.setStatus(302)

(2)第二部分:响应头 

响应头是key-value结构,一个key可以有一个value,一个key也可以有多个value。 
常用方法:

方法 作用
setHeader(java.lang.String name, java.lang.String value) 设置响应头
两个参数:第一个参数是响应名称;第二个参数值
setIntHeader(java.lang.String name, int value) 针对int类型值的方法
setDateHeader(java.lang.String name, long date) 值long类型,是毫秒数(1970 1 1至今的毫秒数)
addHeader(java.lang.String name, java.lang.String value) 设置响应头
两个参数:第一个参数是响应名称;第二个参数值
addIntHeader(java.lang.String name, int value) 针对int类型值的方法
addDateHeader(java.lang.String name, long date) 值long类型,是毫秒数

setHeader和addHeader的区别: 

setHeader会将之前的值覆盖掉,而addHeader可以添加多个响应头。

(3)第三部分:响应体,向页面显示的内容 

常用方法:

方法 作用
getWriter() 使用字符流向页面输出内容
getOutputStream() 使用字节流向页面输出内容

14.1. 重定向的案例

当注册一个网站,注册完成之后,5秒之后跳转到登录页面。 

实现方式:使用头信息Refresh实现

response.setHeader("Refresh","在几秒值后跳转;url=要跳转到页面的路径");

创建servlet,在servlet实现,在五秒之后跳转到一个页面:

response.setHeader("Refresh", "5;url=/day08-1/login.html");

14.2. 设置响应体(向页面输出内容)

14.2.1. 使用字节流向页面输出内容

代码:

response.getOutputStream().write("输出的内容".getBytes());

如果向页面输出中文,根据不同的浏览器的编码设置会产生乱码问题。产生原因:浏览器的编码和字节数组的编码不一致。 

解决方法:让浏览器的编码和字节数组的编码一致 
1、设置浏览器的编码 
2、设置字节数组的编码

//设置浏览器的编码 使用头信息 Content-Typeresponse.setHeader("Content-Type", "text/html;charset=utf-8");//设置字节数组的编码response.getOutputStream().write("字节流中文".getBytes("utf-8"));

14.2.2. 使用字符流向页面输出内容

代码:

response.getWriter().write("response");

如果使用字符流向页面输出中文,一定会有乱码 

原因:使用字符流向页面输出内容;首先会把内容放到response缓冲区里面,response缓冲区默认的编码是 iso8859-1,这个编码不支持中文,一定会有乱码。 
解决方法:response缓冲区的编码和浏览器的编码一致。 
1、设置response缓冲区的编码 
2、设置浏览器的编码

//设置response缓冲区的编码response.setCharacterEncoding("utf-8");//设置浏览器的编码response.setHeader("Content-Type", "text/html;charset=utf-8");response.getWriter().write("字符流中文");

14.3. response的流的注意事项

(1)使用字符流向页面输出中文乱码问题解决,简写方式

response.setContentType("text/html;charset=utf-8");
  •  

(2)字节流和字符流是互斥的 

(3)使用字符流不能直接向页面输出数字

//根据数字到码表中查询数字对应的字符,把字符输出response.setCharacterEncoding("utf-8");response.getWriter().write(111);

15. 文件下载的案例

(1) 设置头信息 Content-Disposition,无论是什么格式的文件都以下载方式打开 

(2) 在服务器上面有一个可以下载的文件 
(3) 从服务器上拿到这个文件(使用文件输入流得到文件) 
(4) 使用输出流把文件写到浏览器

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {   // 得到要下载文件的路径   String path = getServletContext().getRealPath("/down/a.zip");   // 得到文件的名称   int lens = path.lastIndexOf("\\");   String filename = path.substring(lens + 1);   // 设置头信息   response.setHeader("Content-Disposition","attachment;filename=" + filename);   // 得到文件的输入流   InputStream in = new FileInputStream(path);   // 使用输出流操作   OutputStream out = response.getOutputStream();   // 流对接   int len = 0;   byte[] b = new byte[1024];   while ((len = in.read(b)) != -1) {     out.write(b, 0, len);   }   // 关闭流   in.close();}

16. Request对象

request代表请求的对象,HttpServletRequest接口,父接口是ServletRequest。

16.1. 获取请求行的信息

方法 作用
getMethod() 得到http请求方式
getRequestURI() 得到请求地址(不包含ip+端口号)
getProtocol() 得到http的版本

16.2. 获取请求头的信息

方法 作用
getHeader(java.lang.String name) 根据名称得到请求头的值,如:头信息 User-Agent:获取当前请求的浏览器的类型
String agent = request.getHeader(“User-Agent”);

16.3. 获取客户机的信息

方法 作用
getContextPath() 请求项目的名称
getRequestURL() 客户端发送的请求的路径
getRemoteAddr() 获取当前客户端的ip地址

16.4. 获取表单提交的数据

(1)String getParameter(java.lang.String name) :参数是表单输入项name属性的值,根据名称得到输入的值 

代码:

String username = request.getParameter("username");String password = request.getParameter("password");

(2)String[] getParameterValues(java.lang.String name) :参数是表单输入项name的值,针对复选框的情况 

代码:

String[] loves = request.getParameterValues("love");

(3)String[] getParameterValues(java.lang.String name) : 

返回的是map集合,key是表单输入项name属性的值,value是输入的值 
代码:

Map
map = request.getParameterMap();//得到map集合里面的key和value,遍历mapSet
keys = map.keySet();//遍历set集合for (String key : keys) {//根据key得到valueString[] values = map.get(key); //key和对应的value输出(表单输入项name的属性值和输入的值) System.out.println(key+" :: "+Arrays.toString(values));}

(4)Enumeration

16.5. 获取表单提交的中文数据乱码问题

(1)post提交方式解决方法 

使用post提交数据时候,会把数据放到request缓冲区里面,request缓冲区默认的编码 iso8859-1,不支持中文。 
解决方法: 
设置request缓冲区的编码 
代码:

request.setCharacterEncoding("utf-8");

(2)get提交中文乱码解决 

有三种方式 
第一种:修改tomcat的配置文件

第二种:把数据先编码,再进行解码 

第三种:使用string构造进行编码,new String(“”); 
代码:

username = new String(username.getBytes("iso8859-1"),"utf-8");

16.6. request是域对象

(1) 域对象:在一定的范围内,可以存值和取值。 

(2) servletContext域对象:范围是整个web项目,存值setAttribute方法和取值getAttribute方法。 
(3) request也是一个域对象:范围是一次请求,存值和取值。 
向request域里面存值的方法:setAttribute(java.lang.String name, java.lang.Object o); 
从request域里面取值的方法:getAttribute(java.lang.String name)。 
(4) request域对象范围是一次请求,经常和转发一起使用 
代码request.getRequestDispatcher(“转发的路径不带项目名称”).forward(..); 
(5) 举例演示request域对象 
创建servlet1,在servlet1里面向request域里面设置一个值,最后转发到servlet2里面:

//向request域里面设置一个值request.setAttribute("msg", "itcast100");//转发到servlet2request.getRequestDispatcher("/servlet2").forward(request, response);

创建servlet2,在servlet2里面获取通过servlet1向request域里面设置的那个值

//获取通过servlet1向request里面设置的值response.getWriter().write(""+request.getAttribute("msg"));

16.7. 重定向和转发的区别

(1)重定向 

请求次数:重定向请求两次,请求的地址带项目名称 
实现方式:302+Location实现重定向的操作 
实现代码:response.sendRedirect(“路径 带项目名称”);

(2)转发 

请求次数:转发请求一次,路径不需要带项目名称(在服务器内部进行操作) 
实现代码:request.getRequestDispatcher(“转发的路径 不带项目名称”).forward(request, response);

(3)重定向:从一个网站到另外的一个网站 

转发:请求的过程中需要携带数据操作

17. 文件上传

17.1. 什么是文件上传

把本地的文件存储到服务器上,这个过程称为文件的上传。比如,网盘、qq空间。

17.2. 文件上传的实现

(1) jspSmartUpload:应用在jsp的模型一 

适于嵌入执行上传下载操作的JSP文件中 
(2) fileUpload:应用在jsp的模型二(mvc) 
FileUpload 是 Apache commons下面的一个子项目 
组件FileUpload依赖于Commons IO组件 
导入jar包(有两个jar包) 
(3) 要想使用第三方的技术实现文件的上传,首先导入jar包

17.3. 文件上传需要满足的条件

第一个要求:表单,提交方式是post 

get提交方式:地址栏会携带数据,get大小有限制 
第二个要求:在表单里面有文件上传项,必须有name属性 
第三个要求:在form里面,设置一个属性值enctype,设置为multipart/form-data

18. 文件上传的原理的分析(画图)

首先,找到分割线; 

第二,根据分割线区别不同的项; 
第三,普通输入项得到值; 
第四,文件上传项,得到文件的内容,把内容写到服务器里面的一个文件中(使用输入流得到文件的上传内容,使用输出流把文件内的内容写到服务器上) 
这里写图片描述

19. 代码实现文件上传

19.1. 文件上传代码实现的步骤

第一步:创建磁盘文件项工厂

new DiskFileItemFactory();
  • 1

第二步:创建核心上传类

new ServletFileUpload(FileItemFactory fileItemFactory);

第三步:使用核心上传类解析request对象

parseRequest(javax.servlet.http.HttpServletRequest request)返回的List集合,集合里面有多个FileItem,List

第四步:遍历list集合,得到每个FileItem

第五步:判断是普通输入项还是文件上传项

boolean isFormField()

第六步:如果是普通输入项得到值;如果是文件上传项编写上传的代码 

普输入项:

getFieldName():得到普通输入项name的属性的值getString():得到普通输入项里面输入的值

文件上传项:

得到通过表单提交过了的文件的输入流,getInputStream()创建输出流,把文件的输入流写到服务器的一个文件中。

19.2. 代码实现

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        try {            // 创建磁盘文件项工厂            DiskFileItemFactory factory = new DiskFileItemFactory();            // 设置缓冲区大小和临时文件路径            factory.setSizeThreshold(1 * 1024 * 1024); // 字节            String temp = getServletContext().getRealPath("/temp");            factory.setRepository(new File(temp));            // 创建核心上传类            ServletFileUpload fileUpload = new ServletFileUpload(factory);            // 设置上传文件名的编码            fileUpload.setHeaderEncoding("utf-8");            // 设置上传文件的大小            // fileUpload.setFileSizeMax(1*1024*1024); //字节            // 解析request对象            List
list = fileUpload.parseRequest(request); // 遍历list集合 for (FileItem fileItem : list) { // 判断普通输入项 if (fileItem.isFormField()) { // 得到普通输入项的name的属性值和输入的值 String name = fileItem.getFieldName(); String value = fileItem.getString("utf-8"); System.out.println(name + " :: " + value); } else { // 得到上传文件的名称 getName() // 在某些浏览器里面,得到的是全路径名称 c:\aa\1.txt String filename = fileItem.getName(); // 判断是否带 \,如果带 \进行截取 int lens = filename.lastIndexOf("\\"); if (lens != -1) { // 截取 filename = filename.substring(lens + 1); } // 在文件名称里面添加随机的唯一的值 String uuid = UUID.randomUUID().toString(); // uuid_filename filename = uuid + "_" + filename; // 得到提交的文件的输入流 InputStream in = fileItem.getInputStream(); // 得到文件夹的带盘符的路径 ,servletContext对象 String path = getServletContext().getRealPath("/upload"); // 创建输出流 OutputStream out = new FileOutputStream(path + "/" + filename); // 流对接 int len = 0; byte[] b = new byte[1024]; while ((len = in.read(b)) != -1) { out.write(b, 0, len); } in.close(); out.close(); // 删除临时文件 fileItem.delete(); } } } catch (Exception e) { e.printStackTrace(); } }

20. 核心api的使用

DiskFileItemFactory(int sizeThreshold, java.io.File repository) 

有两个参数: 
第一个参数设置上传文件的缓冲区的大小; 
第二个参数是如果上传文件超出了缓冲区,产生临时文件,设置临时文件路径。 
DiskFileItemFactory() 
setSizeThreshold(int sizeThreshold):设置上传文件的缓冲区的大小 
setRepository(java.io.File repository):设置临时文件路径

20.2. ServletFileUpload

ServletFileUpload(FileItemFactory fileItemFactory)

方法 解释
parseRequest(javax.servlet.http.HttpServletRequest request) 解析request对象,返回List集合,集合里面每个部分是FileItem。
setHeaderEncoding(java.lang.String encoding) 设置上传文件名称的编码
setFileSizeMax(long fileSizeMax) 设置单个上传文件的大小
setSizeMax(long sizeMax) 设置上传文件的总大小

20.3. FileItem:文件项

方法 解释
boolean isFormField() 判断是否是普通输入项,返回boolean,如果返回true是普通输入项
getFieldName() 得到普通输入项name的属性值
getString() 得到普通输入项输入的值
getString(java.lang.String encoding) 输入的值有中文,设置编码
getName() 得到上传文件的名称。在某些浏览器里面得到带路径的名称,截取操作
getInputStream() 得到表单提交的文件的输入流
delete() 删除临时文件

21. 文件上传问题的解决

文件重名的问题:如果上传了多个项目名称的文件,最后一次上传的文件,把之后的文件给覆盖了。 

解决方法:在上传的文件名称前面,添加一个随机的唯一的字符串,保证每个文件名称都是唯一的一个值: 
第一种方式:使用当前时间毫秒数实现 
第二种方式:使用UUID工具类实现 
代码:

//在文件名称里面添加随机的唯一的值String uuid = UUID.randomUUID().toString();//uuid_filenamefilename = uuid+"_"+filename;

转载于:https://my.oschina.net/u/2884845/blog/742763

你可能感兴趣的文章
VMware下的Linux中调整屏幕大小,分辨率问题,终于解决啦
查看>>
cxgrid打印
查看>>
ANDRO - MULTIPURPOSE OPENCART 2.X 自适应主题模板 ABC-0651-02
查看>>
必 备 习 题 集 ( 三 )
查看>>
citrix桌面发布方式
查看>>
HTTP协议详解(真的很经典)
查看>>
EMC销售部全球CTO Patricia Florissi:大数据不是炒作
查看>>
判断字符串是否是合法的ipv4地址
查看>>
Linux系统手动安装rzsz 软件包
查看>>
Hyper-V安装笔记
查看>>
Golang面试题解析(二)
查看>>
Juniper SRX与思科跑IPSEC ×××+OSPF
查看>>
C语言学习之路(1)
查看>>
passwd修改用户密码
查看>>
Windows Phone(三)WP7版 " 记账本" 开发(使用SQLite数据库)
查看>>
CSS 几款比较常用的翻转特效(转载)
查看>>
html5 拖拽事件
查看>>
Spring创建对象的三种方式以及创建时间
查看>>
IO多路复用, 基于IO多路复用+socket实现并发请求(一个线程100个请求), 协程
查看>>
大白话Vue源码系列(03):生成AST
查看>>