Android基础第五篇

原创 2016年08月29日 22:08:22

转载请标明出处:
http://blog.csdn.net/gj782128729/article/details/52357005
本文出自:【高境的博客】

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

<servlet>
    <servlet-name>servletDemo1</servlet-name>
    <servlet-class>com.gaogao.servlet.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>servletDemo1</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

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()方法执行。
这里写图片描述

3. Servlet的生命周期


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标签里面写标签:

<load-on-startup>正整数的值</load-on-startup>

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<String> 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)配置全局初始化参数

<context-param>
    <param-name>url</param-name>
    <param-value>localhost</param-value>
</context-param>

(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<String> 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得到类加载器
代码:

//得到类的Class
Class 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

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>
          org.apache.catalina.servlets.DefaultServlet
    </servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

在默认的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-Type
response.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<String,String[]> map = request.getParameterMap();
//得到map集合里面的key和value,遍历map
Set<String> keys = map.keySet();
//遍历set集合
for (String key : keys) {
//根据key得到value
String[] 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的配置文件

<Connector port="80" protocol="HTTP/1.1"
     connectionTimeout="20000"
     redirectPort="8443" URIEncoding="utf-8"/>

第二种:把数据先编码,再进行解码
第三种:使用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");
//转发到servlet2
request.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();

第二步:创建核心上传类

new ServletFileUpload(FileItemFactory fileItemFactory);

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

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

第四步:遍历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<FileItem> 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_filename
filename = uuid+"_"+filename;
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java基础知识--第五篇

一 二维数组:一维数组的数组。 动态初始化方式一(指定有多少个长度相同的一维数组): 数据类型[][] 变量名 = new 数据类型[m][n]; m表示这个二维数组有多少个一维数组 n...

Struts2学习(第五篇)——action基础知识和数据校验

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188   一:首先看一下struts2中action的实现方式: 1.建立普通...

黑马程序员——Java基础之函数——第五篇

---------------------- android培训、java培训、期待与您交流! ----------------------  提纲: 函数的定义 函数的特点 函数的应用 函...

【SSH三大框架】Hibernate基础第五篇:利用Hibernate完成简单的CRUD操作

用Hibernate完成简单的CRUD操作

Android插件化开发 第五篇 [360 Droid Plugin]

引言上篇文章为止我们有完整的介绍Android插件开发的流程。简单的回顾一下就是通过系统的ClassLoader加载插件apk里的方法,通过反射与插件交互。说起来容易实现起来却是一步一个坑,所以这篇文...

Android提高第五篇之Service

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!        上次介绍了Activity以及Intent的使用,这次就介绍Service,如果把Activit...

android emulator虚拟设备分析第五篇之pipe上的opengles

一、概述 二、opengles —— pipe上的另一个service 三、使用host gpu

Android开源项目第五篇——优秀个人和团体篇

Android开源项目第五篇——优秀个人和团体篇 本文为那些不错的Android开源项目第五篇——优秀个人和团体篇,主要介绍那些乐于分享并且有一些很不错的开源项目的个人和组织(公...

Android UI开发第五篇——自定义列表

自定义列表,设置列表背景、列表的列背景、列表的间隔线。借鉴了一些前辈的代码。MainActivity.classpublic class MainActivity extends Activity {...

Android Ap 开发 设计模式第五篇:单件模式

Singleton Pattern 名称由来 java 是一门面向对象的语言,android 用的也是java 开发ap ,在java/C#  里面所有的物体(类)都可以看作是一个对象,而要使用这...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)