Tomcat与JavaWeb开发技术详解Servlet技术下第五章

5.1下载文件

下载文件是指把服务器端的文件发送到客户端

具体步骤:

OutputStream out;//输出相应正文的输出流

  InputStream in;//取得本地文件的输入流
  String filename=request.getParameter("filename");//获得请求参数

in=getServletContext().getResourceAsStream("/store/"+filename);//获得store目录下的相应文件输入流

//设置相应正文的MIME类型

  int length=in.available();
  response.setContentType("application/force-dowload");
  response.setHeader("Content-Length", String.valueOf(length));
  response.setHeader("Content-Disposition", "attachment;filename=\""+filename+"\"");

 //把本地文件中的数据发送给客户

  out=response.getOutputStream();
  int byteRead =0;
  byte[] buffer=new byte[512];
  while ((byteRead=in.read(buffer))!=-1) {
   out.write(buffer, 0, byteRead);
   in.close();
   out.close();
   
  }//读取文件数据,并通过输出流把文件中的数据送到客户端

通过浏览器访问http://localhost:8080/helloapp/download?finame=XXXX.rar

扫描二维码关注公众号,回复: 2228365 查看本文章

5.2文件上传

具体步骤:

在upload.html文件的代码如下

<form name="uploadForm" method="post" enctype="MULTIPART/FORM-DATA0" action="upload">

<table>
<tr>
<td><div align="right">User name:</div></td>
<td><input type="text" name="username" size="30"/></td>
</tr>
<tr>
<td><div align="right">Upload File1:</div></td>
<td><input type="file" name="file1" size="30"/></td>
</tr>
<tr>
<td><div align="right">Upload File2:</div></td>
<td><input type="file" name="file2" size="30"/></td>
</tr>
<tr>
<td><input type="submit" name="submit" value="upload"></td>
<td><input type="reset" name="reset" value="reset"></td>
</tr>
</table>
</form>

在servlet中可利用Apache开源软件组织提供的两个软件包来实现文件上传

fileupload软件包:

http://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi

io软件包:

http://commons.apache.org/proper/commons-io/download_io.cgi

软件包把请求正文包含的复合表单的每个子部分看作是一个FileItem对象,分为两种类型:formFile(普通表单域类型)非formField(上传文件类型)

FileItemFactory是创建FileItem对象的工厂,DiskFileItemFactory类和DiskFlieItem类分别实现了FileItemFactory接口和FileItem接口。DiskFlieItem能够把客户端上传的文件数据保存到硬盘上,DiskFileItemFactory则是DiskFlieItem对象的工厂。

以下代码创建了一个DiskFileItemFactory对象,然后设置了在向硬盘写数据时所用的缓冲区的大小,以及所使用的临时目录:

//创建一个基于硬盘的FileItem工厂

   DiskFileItemFactory factory=new DiskFileItemFactory();
   //向硬盘写数据时所用的缓冲区的大小,此处为4K
   factory.setSizeThreshold(4*1024);
   //设置临时目录
   factory.setRepository(new File(tempFilePath));

ServletFileUpload为上传处理器,与FileItemFactory关联:

//创建一个文件上传器

   ServletFileUpload upload=new ServletFileUpload(factory);
   //设置允许上传的文件的最大尺寸为4M
   upload.setSizeMax(4*1024*1024);

ServletFileUpload类的parseRequest(HttpServletRequest req)方法能够解析HttpServletRequest对象中的复合表单数据,返回一组FileItem对象集合:

List items=upload.parseRequest(request);

然后遍历集合,判断每个FileItem对象的类型做相应的处理

   Iterator iter=items.iterator();
   while (iter.hasNext()) {
    FileItem item=(FileItem)iter.next();
    if (item.isFormField()) {
     processFormField(item, outNet);//处理普通表单
    }
    else {
     processUploadedFile(item, outNet);//处理上传文件
    }
   }

web.xml文件中的UploadServlet的配置代码如下:

<servlet>

    <servlet-name>upload</servlet-name>
    <servlet-class>mypack.UploadServlet</servlet-class>
   
    <init-param>
    <param-name>filePath</param-name>
    <parm-value>store</parm-value>
    </init-param>
     <init-param>
    <param-name>tempFilePath</param-name>
    <parm-value>temp</parm-value>
    </init-param>
   <servlet-mapping>

    <servlet-name>upload</servlet-name>
    <url-pattern>/upload</url-pattern>
  </servlet-mapping>

5.3动态生成图像(略)

5.4读写Cookie

Cookie是客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,服务器可根据Cookie来跟踪客户状态。当客户端首次请求访问服务器时,服务器现在客户端存放该客户相关信息的Cookie信息,以后客户端每次访问服务器时,都会在Http请求数据中包含Cookie信息,服务器解析Http请求中的Cookie,就能获得关于客户的信息。

Web服务器为了支持Cookie,需具备以下功能:

把Cookie添加到HTTP响应中

   cookie=new Cookie("username", "Tom");
   cookie.setMaxAge(60*60);
   response.addCookie(cookie);

读取来自客户端的Cookie

Cookie [] cookies=request.getCookies();

调用getName()方法获得Cookie名字,调用getValue()方法获得Cookie的值

    out.println("Cookies name:"+cookies[i].getName());
    out.println("Cookies value"+cookies[i].getValue());

可以通过Cookie类的setMaxAge()方法设置Cookie的有效期

5.5访问Web应用的工作目录

Servlet可通过以下方式获得Web应用的工作目录
File workDir=(File)context.getAttribute("javax.servlet.context.tempdir");

5.6转发和包含

Servlet规范为web组件之间的协作提供了两种途径:(1)请求转发(2)包含
公共的特点:
(1)源组件和目标组件处理的都是同一个客户要求,两者共享同一个servletRequest和ServletResponse对象

(2)目标组件都可以是Servlet,Jsp,Html文档

(3)都依赖javax.servlet.RequestDispatcher接口(请求分发器:forward()方法和include()方法)

可以通过两种途径获得RequestDispatch()对象:

调用ServletContext的getRequestDispatch(String path)方法

调用ServletRequest的getRequestDispatch(String path)方法

前者必须为绝对路径,即以“/”开头的路径,应用的入口,后者可以为绝对路径,也可以为相对路径,不以“/”开头

请求转发:

ServletContext context=getServletContext();
  RequestDispatcher dispatcher=context.getRequestDispatcher("/servlet/OutPutStreamServlet");
  dispatcher.forward(request, response);

请求包含:

ServletContext context=getServletContext();
  RequestDispatcher headDispatcher=context.getRequestDispatcher("/Header.html");
  RequestDispatcher greetDispatcher=context.getRequestDispatcher("/servlet/GreetServlet");
  
  headDispatcher.include(request, response);
  greetDispatcher.include(request, response);

 请求范围内的共享数据可通过setAttribute()方法和getAttribute()方法进行数据共享

5.7重定向

用户在浏览器输入特定的URL,请求访问服务器的某个组件,服务器的组件返回一个状态代码为302的响应结果,该响应的含义是让服务再次请求访问另一个Web组件,另一个组件有可能在同一个Web服务器上,也有可能不在同一个Web服务器上。
关键代码:

response.setRedirect("/helloapp/output?msg="+message);//msg的值为message

如果以“/”开头的则是相对路径,如果以“Http://”开头的则是绝对路径

5.8访问Servlet容器内的其他Web应用

在一个Servlet容器进程内,可以同时运行多个Web应用,这些Web应用之间可进行通信。每个Web应用都有一个ServletContext大总管,对于web应用A中的Servlet,只要得到了Web应用B的ServletContext对象,就能访问到Web应用的各种资源。

ServletContext接口中的getContext(String uripath)可以得到其他Web应用的Context对象,uripath为其他web应用对象的入口,在tomcat中,<Context>元素的crossContext对象属性用于设置该选项:crossContext属性为false,则其他应用访问返回null,如果为true则可以访问

代码示例:

ServletContext context=getServletContext();

ServletContext CrossContext=context.getContext("/helloapp");

RequestDispatcher dispatcher=CrossContext.getRequestDispatcher("/servlet/GreetServlet");

dispatcher.forward(request,response);

在XML文件中配置<Context>元素

<context reloadable="true" crossContext="true">

5.9避免并发问题

(1)合理决定在Servlet中定义的变量的作用域类型

局部变量作用于方法之中,方法结束,变量的生命周期也就结束,实例变量作用于类之中,如果一个实例结束,那么它的实例变量也就结束。

(2)使用java同步机制对多线程同步

synchronized(this)

                                                                                                                                  2018.07.09

























猜你喜欢

转载自blog.csdn.net/qq_40369435/article/details/80975776
今日推荐