java web 输出流_JavaWeb入门笔记

本文详细介绍了Java Web中的Servlet,包括HTTP协议、Web服务器、Servlet生命周期、Servlet处理请求流程、请求和响应对象、HTTP请求方法、Servlet间的通信、过滤器和监听器的使用。还讲解了Servlet3.0的注解配置以及文件上传功能,是学习Java Web的实用指南。
摘要由CSDN通过智能技术生成

Java web笔记

一、HTTP协议

HTTP(超文本传输协议),它是一种主流B/S架构中应用的通信协议。具有以下特点:

1、无状态

服务端不会记录客户端每次提交的请求,服务器一旦相应客户端之后,就会结束本次的通信过程。客户端下一次的请求是一个新的 连接,和上一次通信没有任何关系。

2、简单灵活

HTTP是基于请求(request)和响应(response)的模型

3、支持客户端与服务端

支持主流的B/S架构的通信以及C/S架构的通信。

注意:C/S架构可选的协议有多种,例如:TCP/IP,UDP,HTTP

​ 而B/S架构通常只支持HTTP协议

二、服务器

1、概念

服务器通常由硬件和软件部分构成,统一对用户提供多种不同的服务。

1、硬件:包括响应的CPU、内存、磁盘等等

2、软件:包括操作系统、运行环境、服务器软件、数据库等等

2、web服务器

web服务器是提供服务端程序运行的一个环境,它本身也是一个软件。

例如:将我们编写HTML文件放入到web服务器中,那么外界就可以通过浏览器访问我们的html页面

常见的web服务器有Apache,Tomcat、Jetty、Nginx等等。

而Tomcat、Jetty这些web服务器更准确的说是一个Servlet容器。

三、JavaWeb项目结构

项目根目录,例如:myweb、ch01通常存放静态资源文件(如:html等等)

WEB-INF

这个目录是当前项目私有的一个文件夹,只能提供给项目内部访问,对于客户端来说是访问不到了,通常这个目录下存放的是Java源代码、编译后的字节码文件以及Servlet的核心配置文件web.xml

src

存放java源代码的目录

classes

存放编译后的字节码文件

lib

lib目录存放当前项目所需要的jar文件

JSP

用于存放JSP动态页面

web.xml

项目的配置文件,用于配置Servlet的请求映射、过滤器、监听器等等信息。每一个web项目都对应一个web.xml配置文件

META-INF

配置应用程序、扩展程序、类加载服务等等

四、Servlet基础

1、什么是Servlet

Servlet是JavaEE中标准组件,专门用于处理客户端提交的HTTP请求。并且它必须依赖于Servlet容器才可以运行(Tomcat就是一个标准的Servlet容器),Servlet容器给Servlet提供一个运行环境,所以Servlet组件必须要这个环境中可以运行,而不能脱离这个环境而单独执行。因为Servlet的实例是由容器创建和销毁的,并不是通过我们平常使用的new关键创建出来。

2、开发一个Servlet的步骤

1.编写一个类,然后继承HttpServlet这个父类

2.重写父类的service方法,这个就是专门处理客户端请求的方法,这个方法有两个参数(HttpServletRequest,HttpServletResponse),同时这个方法会抛出两个异常(ServletException,IOException)

import javax.servlet.*;import javax.servlet.http.*;import java.io.*;//要让当前的类是一个Servlet,必须继承HttpServlet

public class HelloServlet extendsHttpServlet{//重写父类的service方法,处理客户端请求,//这个方法私有servlet容器去调用,//并且request和response参数都是由servlet容器传递进来的

public void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("Hello Servlet");//响应一些信息回馈给客户端浏览器//1.设置要响应的类型,这里就响应简单的html文本类型//通过response参数来进行设置,如:text/html,text/plain

response.setContentType("text/html;charset=utf-8");//2.获取输出流并写回html数据

response.getWriter().println("

Hello Servlet

");

}

}

3.编译Servlet,需要依赖servlet-api.jar文件

4.编写web.xml,为servlet配置请求映射的URL

hello

HelloServlet

hello

/test

5.将项目部署到Tomcat的webapps目录中

3、servlet处理请求的流程

1.浏览器发起http的请求,这个请求首先会被servlet容器(Tomcat)截获,然后容器会根据web.xml文件中配置servlet的来找到相应的这个别名,然后再根据这个别名找到具体Servlet的类,然后容器会创建这个Servlet类的实例并调用Servlet方法来处理这个请求。

4、Servlet的生命周期

所谓的生命周期,就是从Servlet的创建一直到它销毁的整个过程。并且它的 整个生命周期都是由Servlet容器(Tomcat)负责管理和维护的。(补充:在Tomcat中,Servlet是以单实例多线程的方式处理客户端请求)

4.1 Servlet对象创建的过程

当第一次请求某个Servlet的时候,容器会先查找之前有没有创建过这个Servlet的实例,如果没有则创建一个实例并缓存起来。后续 所有请求这个Servlet的时候,都会使用这个缓存的对象来处理客户端请求。(注意“这里说的是第一次请求时创建。另外一种情况则是在容器启动的时候就创建Servlet的实例,在web.xml中为Servlet指定配置,这个配置的值是一个整形,数值越小,则初始化 的优先级别越高)

4.2 生命周期方法

方法名描述

init

在Servlet对象创建之后立即执行的初始化方法,且只执行一次

service

核心的请求处理方法,这个方法可以执行多次

destroy

容器准备销毁Servlet实例之前执行的方法,也是执行一次

5、HTTP请求报文

5.1 请求报文

请求行:请求报文的第一行就是请求行。包括请求方法、请求URL地址、HTTP协议版本

请求头:请求行之后的信息就是请求头,它是以“名称:内容”的格式体现。主要包括服务器主机地址及端口号、连接状态、接收的数据类型、编码、语言等等

请求体:请求头结束之后会有一个空行,空行之后就是请求体的内容。通常使用POST提交的数据信息会存放在请求体中,然后传递给服务器。

5.2 响应报文

状态行:主要包括HTTP协议、响应状态码(例如:200表示OK,成功响应)

响应头:主要包括服务器信息、响应的类型及编码、内容的长度、响应的时间等

响应体:服务器将信息携带到响应体中,带回客户端。

6、HTTP请求方法

在HTTP/1.1协议中,请求方法主要包括8个,下面列举常用的请求方法进行说明。

请求方法说明

GET

向服务器请求指定的资源,并返回响应主体。一般来说GET方法应该只用于数据的读取(类似于查询)

POST

向指定的服务器提交数据(例如:表单数据的提交、文件上传等),并且提交的数据会放入请求体中(类似于新增)

PUT

向服务器提交数据,但是和POST有所区别。如果服务器不存在此资源的时候,则执行新增,如果存在则执行修改。(类似于修改)

DELETE

根据uri的表示删除服务器上的某个资源(类似于删除)

...

...

备注:GET与POST区别:

1.GET主要用于获取数据,POST用于提交数据。

2.GET请求所带的参数是放在请求行的url地址后面,而POST这是放在请求体中。

3.通常浏览器会对GET请求的url长度有所限制 ,而POST通常在请求体中,可以提交更多的数据信息。

4.浏览器会对GET请求进行缓存。

7、Servlet的请求处理方法

方法说明

service

可以处理任何的请求类型

doGet

处理对应的GET请求

doPOST

处理对应的POST请求

doPut

处理对应的PUT请求

doDelete

处理对应的DELETE请求

说明:通过HttpServlet的源代码得知,默认的所有请求都会先经过service方法,然后service方法根据请求的方法类型判断来决定交给doGet或者是doPOST方法来处理请求。如果子类重写了service方法同时还重写了其他的doXxx的方法,那么只有service方法会处理请求,其他方法将失效。

8、请求和响应对象

当web容器调用某个Servlet的Service方法时,会创建一个HTTPServletRequest和HTTPServletResponse对象作为参数传入到这个方法中,那么我们可以通过HTTPServletRequest来获取相关的请求内容等,而响应客户端可以利用HttpServletResponse对象来完成。

8.1 HttpServletRequest常用API

方法说明

getParameter(String name)

获取请求参数的值,根据请求参数的name指定

getParameterValues(String name)

获取相同name的请求参数,返回的是字符串数组

getParameterMap()

获取所有请求参数,包括参数名称和值

getMethod()

获取请求方法的类型

getHeader(Stirng name)

根据请求头的名称获取响应的信息

getRemoteAddr()

获取远程客户端的IP地址

getServletPath()

获取Servlet的请求地址,也就是url-pattern

getRequestURL()

获取请求完整的URL地址

getRealPath(String path)

获取项目的绝对路径。(这个方法在request对象中已废弃,建议通过ServletContext对象获取)

其他

...

public void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException{

System.out.println("---------------获取参数值----------------");//获取请求参数,根据请求的参数名

String name = request.getParameter("uname");

String age= request.getParameter("age");

System.out.println(name);

System.out.println(age);//获取相同参数名的参数

String[] addrs = request.getParameterValues("address");for(String addr : addrs) {

System.out.println(addr);

}

System.out.println("--------------获取参数名---------------");//获取所有的参数名

Enumeration es =request.getParameterNames();//枚举使用迭代器来循环遍历

while(es.hasMoreElements()) {

String paramName=es.nextElement();

System.out.println(paramName);

}

System.out.println("---------------获取所有的参数名和参数值-------------------");//map泛型的第一个参数表示请求的参数名称,第二个参数是请求的参数值,值可以有多个,所以是数组

Map map =request.getParameterMap();//map的key对应的是参数名,value就是参数的值

for(String key : map.keySet()) {

System.out.println("参数名:" +key);

System.out.println("参数值: ");

String[] values=(String[])map.get(key);for(String value : values) {

System.out.println(value);

}

System.out.println("~~~~~~~~~~~");

}

System.out.println("-------------获取客户端的请求方法--------------");

String method=request.getMethod();

System.out.println("请求方法:" +method);

System.out.println("--------------获取请求头部的信息---------------");

String header= request.getHeader("Host");

System.out.println("请求头信息:" +header);

System.out.println("--------------获取远程客户端的IP地址--------------");

String addr=request.getRemoteAddr();

System.out.println("客户端的IP地址" +addr);

System.out.println("------------获取Servlet的url-pattern---------------");

String servletPath=request.getServletPath();

System.out.println("url-pattern: " +servletPath);

System.out.println("------------获取请求的完整URL---------------------------");

String url=request.getRequestURL().toString();

System.out.println(url);

System.out.println("-------------获取项目的绝对路径------------------");

String path= request.getServletContext().getRealPath("/");

System.out.println(path);

}

8.2 HttpServletResponse常用API

方法说明

setContentType(String str)

设置响应内容的类型及编码

getWriter()

获取响应字符输出流

getOutputStream()

获取字节输出流

setHeader(String name,String value)

设置响应头信息,如果存在响应头信息,则执行更新

addHeader(String name,String value)

设置响应头,不管存不存在都会新加入一个

setStatus(int code)

设置响应状态码

其他

...

public void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//设置响应的内容类型及编码,包括(text/html,text/plain,application/json)

response.setContentType("text/html;charset=utf-8");//设置响应头信息

response.addHeader("myheader", "hello header");

response.addHeader("myheader", "my servlet");//设置响应的状态码

response.setStatus(200);//获取字节输出流

OutputStream os =response.getOutputStream();//获取响应的字符输出流

PrintWriter pw =response.getWriter();

pw.println("");

pw.println("

index");

pw.println("

");

pw.println("

Hello Servlet

");

pw.println("");

pw.println("");

}

9239782.html

8.3 常见的响应状态码

状态码说明

200

请求成功

401

禁止访问,未授权

404

找不到请求的资源

405

请求的行的方法不被支持

500

服务器内部错误

其他

...

9、Servlet之间的通信

9.1 转发

所谓转发,就是在多个Servlet之间共享请求和响应对象,所有参与转发过程的Servlet都可以获取同一个请求对象的信息。在Servlet的API中,转发的操作是有HttpServletRequest对象完成的。

示例代码:

public class ServletA extendsHttpServlet{public void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException{//获取页面提交的参数

String name = request.getParameter("userName");//转发由HttpServletRequest完成//第一步先获取一个请求转发器RequestDispatcher//获取请求转发器的同时要告诉转发器转发到哪里,转发给谁//如果要转发给ServletB,那么就是对应ServletB的url-pattern

RequestDispatcher rd = request.getRequestDispatcher("servletB");//调用转发器的forward方法执行转发,同时将request和response对象一并转发ServletB

rd.forward(request, response);

}

}

public class ServletB extendsHttpServlet{

@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//这里在同一个请求中再次获取页面的参数

String name = request.getParameter("userName");

System.out.println("ServletB获取请求参数:"+name);

}

}

转发的特点:

1、URL地址栏不会发生改变

2、转发的过程是在服务端自动完成

请求作用域:

每一个请求对象都有一个独立的空间,这个空间我们称之为请求作用域(RequestScope),可以为当前这个请求携带额外的一些数据信息,这些信息同样可以在多个Servlet之间进行共享。

示例代码:

public class ServletA extendsHttpServlet{public void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException{//在ServletA中为request对象设置请求作用域

request.setAttribute("age", 35)

}

}

public class ServletB extendsHttpServlet{

@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//在ServletB中获取统一个请求对象作用域的值域的值

Integer age = (Integer)request.getAttribute("age");

}

}

9.2 重定向

重定向的机制和转发不同,一次重定向的过程中会有两次请求和两次响应,服务端在接收第一次请求后会先做一次302的响应(302表示重定向状态码),告诉客户端浏览器必须发起一个新的地址,服务端再次接收这个请求处理,最后再次响应客户端。

4ab9a264db81bcc9bb48760a49169c0b.png

9239782.html

重定向特点:

1、URL地址栏会发生改变

2、重定向的操作是在客户端浏览器完成的

示例代码:

方式一:

public class ServletC extendsHttpServlet {

@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//执行重定向//方式一:设置302响应状态码,并在响应头中添加location属性指定重定向的地址

response.setStatus(302);

response.addHeader("location", "http://localhost:8080/ch06/servletD");

}

}

方式二:

public class ServletC extendsHttpServlet {

@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

System.out.println("请求到达ServletC");

System.out.println("ServletC获取请求参数:"+request.getParameter("userName"));//执行重定向//方式二:使用response的sendRedirect方法

response.sendRedirect("servletD");

}

}

10、会话跟踪

由于HTTP协议是无状态的,服务端并不会记录每一个客户端的状态,因此,如果想要实现服务器能记录客户端的状态的话,那么就需要会话跟踪技术。

10.1 cookie

cookie是客户端浏览器的内部的一个文本文件,专门用于记录服务器发送过来的一些文本信息,那么在每次请求的时候,客户端都把这个cookie信息由提交回给相应的服务器,那么服务器就可以获取cookie的信息,达到会话跟踪的目的。使用cookie的机制是基于客户端浏览器来维护与服务器的状态跟踪。

97d173ab545966f37e1e78bf144f6c7e.png

9239782.html

示例代码:

设置cookie

public class SetCookieServlet extendsHttpServlet{protected void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//创建一个Cookie的实例

Cookie cookie = new Cookie("userId","10001");//将cookie对象设置到响应对象中

response.addCookie(cookie);

System.out.println("成功设置cookie");

}

}

获取cookie

public class GetCookieServlet extendsHttpServlet{

@Overrideprotected void service(HttpServletRequest request, HttpServletResponse repsonse) throwsServletException, IOException {//cookie是通过request对象来得到的//从请求中可以获取多个cookie对象

Cookie[] cookies =request.getCookies();for(Cookie cookie : cookies) {//判断cookie,只获取name为userId的cookie对象

if("userId".equals(cookie.getName())) {

System.out.println(cookie.getValue());

}

}

}

}

cookie保存中文:

在保存cookie的时候如果需要保存中文,那么中文信息需要经过编码后才可以写入cookIe

示例代码:

编码使用URLEncoder

String str=URLEncoder.encode("张三","utf-8");

Cookie cookie= new Cookie("userName",str);

解码使用URLDecoder

String str=URLDecoder.decode(cookie.getValue(),"utf-8");

System.out.println(str);

cookie的生命周期:

默认cookie只会保存在浏览器进程的内存中,并不会写入cookie文件,如果关闭了浏览器,那么浏览器的进程也就消失了,那么对应的内存就会释放空间,因此cookie的也就销毁。如果想将cookie写入文件,那么就必须设置cookie的生命时长,一旦设置了生命时长,那么就表示这个cookie会在文件中保留多长时间,到了这个时间之后,浏览器就会自动销毁这个cookie。

设置cookie存活时间:

//设置为0表示立即删除cookie

cookie.setMaxAge(0);//设置为正数表示cookie在cookie文件的存活时间,单位:秒

cookie.setMaxAge(5);//设置为-1表示cookie只保留在浏览器的进程中,关闭浏览器之后会销毁cookie

cookie.setMaxAge(-1);

10.2 Session

Session是基于服务端来保存用户的信息,这个是和cookie的最大区别。不同的客户端在请求服务器的时候,服务器会为每一个客户端创建一个Session对象并保存在服务器端,这个Session对象是每个客户端所独有的,相互之间不能访问。服务器为了区别不同的Session属于哪一个客户端,因此Session对象也有一个唯一标识,叫做SessionID。而这个SessionID是以cookie的机制保存在客户端浏览器。每次请求的时候,浏览器都会把这个SessionID带回服务端,服务端根据这个SessionID就可以找到对应的Session对象。

示例代码:

public class SessionServlet extendsHttpServlet{

@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {//HttpSession对象是在第一次调用request的getSession()方法时才会创建//注意:getSession()的方法会先判断之前是否为客户端创建了session实例,//如果创建了,则使用之前创建好的Session对象,没有则创建一个新的Session

HttpSession session =request.getSession();//创建HttpSession的同时,会创建一个唯一的标识SessionID//这个sessionId会保存在浏览器的cookie中,每次请求会带回这个id找到相应的session对象

String sessionId =session.getId();

System.out.println(sessionId);

}

}

session的生命周期:

1.SessionId是保存在浏览器的cookie中,但是不会写入cookie文件,这也就表示当关闭浏览器之后SessionId就会销毁。SessionId销毁以后,服务端的Session就没有任何作用了。但是服务器并不会立刻销毁这个Session对象,至于什么时候销毁是由服务器自己决定的。除非我们手动调用了session.invalidate()方法,服务器就会立即销毁这个session实例。

示例代码:

HttpSession session=request.getSession();//立即销毁session

session.invalidate();

2.Session默认也有存活时间,服务器在创建Session的时候为Session设置默认的存活时间为30分钟,如果在30分钟之内,客户端没有发起任何到服务器,那么服务器就会销毁这个Session对象。我们也可以设置Session的存活时间。可以为当前的Session设置,也可以为全局(服务器端的所有Session)的Session设置。

设置当前Session的存活时:

HttpSession session=request.getSession();//设置当前Session的存活时间,单位:秒

session.setMaxInactiveInterval(3600);

设置 全局的Session的存活时间 :

在web.xml中进行设置

60

Session的作用域:

当我们需要将一些数据信息存入Session的时候,就需要操作Session作用域(SessionScope),它和请求作用域类似,也有相应setAttitude和getAttribute方法,只不过Session作用域的范围要比请求作用域更宽。请求作用域在一次请求响应只有就会消失(因为响应之后请求就会销毁)。而Session对象只要浏览器不关闭或者未超时,那么Session对象会一直驻留在服务器端,因此不管重新请求 多少次还是转发和重定向,都可以从Session中获取之前保存的数据信息。

示例代码:

User user = newUser();

user.setUid("1001");

user.setUserName("wangl");

HttpSession session=request.getSession();//将数据保存在会话作用域中

session.setAttribute("user", user);

从会话作用域取值

HttpSession session =request.getSession();//取值

User user = (User)session.getAttribute("user");

URL重写:

浏览器是可以禁用cookie的,一旦禁用了cookie,那么SessionID将无法写入cookie的缓存中,这样就导致无法实现会话跟踪了,因此解决办法就是使用URL重写。URL重写的目的就是把SessionID放在请求URL地址的后面提交回服务器(类似GET请求后面带上参数,而这个参数就是一个SessionID),服务器会解析和这个URL的地址并得到SessionID。

示例代码:

//重写请求的URL地址,这个地址后面会自动带上SessionId

String url = response.encodeRedirectURL("getSession");//重定向URL

response.sendRedirect(url);

浏览器地址演示

http://localhost:8080/ch07/getSession;jsessionid=6F1 BA8C92D7E5D7CC479ED8DD30D3ED0

注意:“;”后面跟着就是SessionID

11、Servlet上下文

web容器在启动时会为每一个web应用创建唯一的上下文对象,这个对象就是Servlet上下文对象(ServletContext),这个上下文对象可以理解为是当前项目的一个共享内存空间,为项目中的所有Servlet提供一个共享的区域。

常用API:

方法说明

getContextPath()

获取项目的相对路径

getRealPath(String path)

获取项目的绝对路径

getInitParameter(String name)

获取上下文的初始化参数(web.xml中配置的)

setAttribute(String name, String value)

将数据放入上下文作用域

getAttribute(String name)

从上下文作用域中去获取数据

上下文作用域:

上下文作用域是为当前项目所有Servlet提供的一个共享内存区域,可以将需要的数据信息保存在作用域中。这个作用域的的范围是最大的,只要容器没有停止,它就会一直存在。

三种作用域:

结合前面所学的作用域,那么一共有三个,分别是:请求作用域,会话作用域,上下文作用域。

范围从小到大来划分:

请求作用域

12、过滤器

过滤器可以在请求到达Servlet之前和Servlet响应客户端之前进行拦截,相当于一个拦截器,主要用于进行一些请求和响应的预处理操作。常用的场景有权限的控制、统一字符编码等等。

017e4835e1fb0ee3bc5647fb2a2b4f45.png

9239782.html

12.1 编写过滤器

要实现一个过滤器,必须实现一个Filter接口,只有实现了这个接口的类才称之为过滤器。

示例代码

public class DemoFilter implementsFilter{

...

}

web.xml配置过滤器:

demoFilter

edu.nf.ch09.filter.DemoFilter

param

hello

demoFilter

/*

12.2 过滤器的生命周期

与Servlet类似,Filter同样也是有容器负责创建和销毁,与Servlet的区别在于,容器会在启动的时候最先创建所有的过滤器,并执行init方法进行初始化。

生命周期方法:

方法说明

init

初始化方法,容器启动时执行一次

doFilter

请求过滤方法,决定请求是否放行

destroy

容器销毁过滤器之前执行的方法

示例代码:

public class DemoFilter implementsFilter{

@Overridepublic voiddestroy() {

System.out.println("准备销毁DemoFilter");

}

@Overridepublic voiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain)throwsIOException, ServletException {//FilterChain表示一个过滤链对象,因为过滤器可能会存在多个//同时这个对象将决定是否放行当前请求,//放行的话则请求会继续到达下一个过滤器或者servlet中

System.out.println("请求经过DemoFileer..放行");

chain.doFilter(request, response);

System.out.println("响应前经过DemoFilter...");

}

@Overridepublic void init(FilterConfig config) throwsServletException {

String name= config.getInitParameter("param");

System.out.println("初始化DemoFilter,获取初始化参数:"+name);

}

}

12.3 过滤链

在一个web项目中可能存在多个过滤器,当有多个过滤器存在的时候就会形成一个过滤链。请求会按照过滤器链的顺序一直传递下去,最终到达某个Servlet来处理请求。(注意:过滤链的顺序是按照web.xml中的先后配置顺序决定的)

配置示例:

firstFilter

edu.nf.ch09.filter.FirstFilter

firstFilter

/*

secondFilter

edu.nf.ch09.filter.SecondFilter

secondFilter

/*

13、监听器

监听器用于监听对象的上的事件发生,在Servlet中监听器主要监听请求对象、会话对象、上下文对象以及监听这些对象的作用操作。JavaEE为我们提供了一系列的监听器接口,开发时按需实现响应的接口即可。

13.1 监听作用域对象的创建于销毁

监听器说明

ServletRequestListener

监听请求对象的创建和销毁

HttpSessionListener

监听会话对象的创建和销毁

ServletContextListener

监听Servlet上下文对象的创建和销毁

代码实例:

1.请求对象监听器

public class DemoRequestListener implementsServletRequestListener{

​/*** 当请求对象销毁后容器执行此方法

* 销毁方法中同样也有一个ServletRequestEvent事件对象*/@Overridepublic voidrequestDestroyed(ServletRequestEvent event) {//通过这个事件对象就可以获取当前的请求对象

HttpServletRequest request =(HttpServletRequest)event.getServletRequest();

System.out.println("销毁请求对象..."+request);

}

​/*** 当请求对象创建之后容器调用此方法

* ServletRequestEvent这个参数就是一个事件对象*/@Overridepublic voidrequestInitialized(ServletRequestEvent event) {//通过这个事件对象就可以获取当前的请求对象

HttpServletRequest request =(HttpServletRequest)event.getServletRequest();

System.out.println("初始化了请求对象..."+request);

}

}

web.xml 配置

edu.nf.ch10.listener.DemoRequestListener

2.会话对象监听器

public class DemoSessionListener implementsHttpSessionListener{

​/*** 监听HttpSession对象的创建

* HttpSessionEvent参数是一个事件对象

* 通过它可以获得当前的HttpSession*/@Overridepublic voidsessionCreated(HttpSessionEvent event) {

HttpSession session=event.getSession();

System.out.println("创建了Session对象"+session);

}

​/*** 监听HttpSession对象的销毁*/@Overridepublic voidsessionDestroyed(HttpSessionEvent event) {

HttpSession session=event.getSession();

System.out.println("销毁了Session对象"+session);

}

}

注意:当第一次调用了request.getSession()方法创建Session时,监听器才会起作用。

web.xml配置

edu.nf.ch10.listener.DemoSessionListener

3.Servlet上下文监听器

public class DemoContextListener implementsServletContextListener{

​/*** 监听ServletContext的销毁*/@Overridepublic voidcontextDestroyed(ServletContextEvent event) {//通过事件对象获取ServletContext

ServletContext sc =event.getServletContext();

System.out.println("销毁了ServletContext对象..."+sc);

}

​/*** 监听SerlvetContext的创建*/@Overridepublic voidcontextInitialized(ServletContextEvent event) {//通过事件对象获取ServletContext

ServletContext sc =event.getServletContext();

System.out.println("创建了ServletContext对象..."+sc);

}

}

web.xml

edu.nf.ch10.listener.DemoContextListener

13.2 监听作用域的操作

监听器说明

ServletRequestAttributeListener

监听请求作用域的操作

HttpSessionAttributeListener

监听会话作用域的操作

ServletContextAttributeListener

监听Servlet上下文作用域的操作

示例代码:

这里以HttpSessionAttributeListener说明,其他作用域监听器用法相似。

public class DemoSessionAttributeListener implementsHttpSessionAttributeListener{

​/*** 当有数据添加到会话作用域时,执行此方法*/@Overridepublic voidattributeAdded(HttpSessionBindingEvent event) {//获取存入作用域的键和值

System.out.println("存入会话作用域..."+event.getName() + " : " +event.getValue());

}

​/*** 当从会话作用域移除数据时,执行此方法*/@Overridepublic voidattributeRemoved(HttpSessionBindingEvent event) {

System.out.println("移除会话作用域..."+event.getName() + " : " +event.getValue());

}

​/*** 当替换了会话作用域中的某个数据时,执行此方法*/@Overridepublic voidattributeReplaced(HttpSessionBindingEvent event) {

HttpSession session=event.getSession();

System.out.println("替换的值: "+session.getAttribute("userName").toString());//注意:这里event.getValue()获取到的是被替换的值

System.out.println("替换会话作用域..."+event.getName() + " : " +event.getValue());

}

}

web.xml

edu.nf.ch10.listener.DemoSessionAttributeListener

14、注解配置

Servlet3.0开始提供了一系列的注解来配置Servlet、Filter、Listener等等。这种方式可以极大的简化在开发中大量的xml的配置。从这个版本开始,web.xml可以不再需要,使用相关的注解同样可以完成相应的配置。

注解说明

@WebServlet

这个注解标识在类上,用于配置Servlet。例如:@WebServlet(name="hello",urlPatterns="/hello")也可以简化配置@WebServlet("/hello")

@WebFilter

这个注解标识在类上,用于配置Filter。例如:@WebFilter(filterName="encode",urlPatterns="/*")也可以简化配置@WebFilter("/*")

@WebListener

这个注解标识在类上,用于配置监听器

15、文件上传

从Servlet3.0开始提供了文件上传的功能,操作起来更加的简单和方便。

15.1

想要使用这个功能,首先必须在web.xml或者使用注解开启Servlet的上传功能,否则无效

xml配置:

upload

edu.demo.UploadServlet

upload

/upload

注解配置:

@WebServlet("/login")

@MultipartConfig//开启上传功能

public class LoginServlet extendsHttpServlet{

...

}

参数说明:

参数说明

location

指定文件上传的目录

maxFileSize

限制单个文件上传的大小

maxRequestSize

限制一次请求上传总文件的大小

fileSizeThreshold

设置缓存的大小,当达到缓存大小的时候,会将内存的数据写入location指定的目录中(也就是写入磁盘)

15.2

文件上传的核心接口是Part,通过HTTPServletRequest对象可获得该接口的实体类对象

//获取单个文件的Part

Part part = request.getPart("name");//获取多个上传文件的Part

Collection cool=request.getParts();

常用API:

方法说明

getContentType()

获取上传的文件类型

getSize()

获取上传文件的大小

getSubmittedFileName()

获取上传文件的文件名

write()

将文件上传(写入)到指定位置

5.13

当客户端使用form表单来上传文件时,必须将表单的enctype属性设置为"multipart/form-data"

Username:

File:

案例:

@WebServlet("/upload")

@MultipartConfigpublic class UploadServlet extendsHttpServlet {

@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {//指定上传的路径

String uploadPath = "/Users/wangl/uploads";//创建文件夹,如果不存在的情况下

File dir = newFile(uploadPath);if(!dir.exists()){

dir.mkdir();

}

​//上传单个文件,参数对用input的name属性的值//Part part = req.getPart("file");//uploadPath = uploadPath + "/" + part.getSubmittedFileName();//执行上传//part.write(uploadPath);//获取文件的类型//System.out.println(part.getContentType());//获取文件的大小//System.out.println(part.getSize());//获取上传的文件名//System.out.println(part.getSubmittedFileName());

​//上传多个文件

Collection parts =req.getParts();for(Part p : parts) {

p.write(uploadPath+ "/" +p.getSubmittedFileName());

}

}

}

upload.html

Title

文件上传

Username:
File1:
File2:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值