javaweb应用程序概述

一、HTTP(超文本传输协议),它是一种主流的B/S架构中应用的通讯协议。具备如下特色:

1.一、无状态:服务不会记录客户端每次提交的请求,服务器一旦响应客户端以后,就会结束本次的通讯过程,客户端下一次的请求是一个新的链接,和上一次通讯没有任何关系html

1.二、简单灵活:HTTP是基于请求和响应的模型java

支持客户端与服务端:web

1.三、支持主流的B/S以及C/S架构的通讯。C/S架构可选的协议有多种,列如:TCP/IP、UDP、HTTP、等,而B/S架构一般只支持HTTP协议。数据库

二、服务器

2.一、概念

服务器同常由硬件和软件部分构成,对用户提供相应的服务express

硬件:包括相应的CPU、内存、磁盘、等等api

软件:包括操做系统、运行环境、服务端软件、数据库等等浏览器

2.二、Web服务器

web服务器是提供服务端程序运行的一个环境,它自己也是一个软件缓存

列如:将咱们编写的html文件放到web容器服务器中,那么外界就能够经过浏览器来访问咱们的HTML页面,tomcat

常见的web服务器有Apache、Tomcat、Jetty、Nginx等等,而Tomcat、Jetty、这些web服务器更准确地来讲是一个Servlet容器服务器

 3. Web项⽬结构

录,例
如:
myweb
ch01
一般存放静态资源⽂件(如: html等等)
WEB-INF 这个⽬录是当前项⽬私有的⼀个⽂件夹,只能提供给项⽬内部访问,对于客户端来讲是访问
不到了,一般这个⽬录下存放的是Java源代码、编译后的字节码⽂件以及Servlet的核⼼配置⽂件web.xml
src 存放Java源代码的⽬录
classes 存放编译后的字节码⽂件
llib lib⽬录存放当前项⽬所须要的jar⽂件
jsp ⻚⾯ ⽤于存放JSP动态
web.xml 项⽬的配置⽂件,⽤于配置Servlet的请求映射、过滤器、监听器等等信息。每⼀个web项⽬都对应⼀个web.xml配置⽂件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4. Servlet基础

4.1 什么是Servlet6

ServletJavaEE中的标准组件之⼀,专⻔⽤于处理客
户端的HTTP请求。而且它必须依赖于Servlet容器
Tomcat就是⼀个标准的Servlet容器)才能够运⾏,
⽽不能脱离这个环境⽽单独执⾏。由于Servlet实例的
建立和销毁都是由容器负责管理的,咱们不能⾃⾏经过
new关键去建立和使⽤它。

 

 

4.2 编写⼀个简单的Servlet

1.在任意地⽅建立⼀个myweb⽂件夹,这个⽂件夹相
当于⼀个项⽬根⽬录
2.在根⽬录下建立WEB-INF⼦⽬录
3.WEB-INF⽬录下建立srcclasses⼦⽬录
4.src⽬录下编写⼀个类,继承HttpServlet这个⽗类

public class HelloServlet extends HttpServlet { } 

 2.重写⽗类的service⽅法,这个就是专⻔处理客户端请
求的⽅法, web容器会为这个⽅法传⼊两个参数
HttpServletRequestHttpServletResponse,而且这个
⽅法还须要抛出ServletExceptionIOException给容
器捕获

public class HelloServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ //设置响应类型及编码 response.setContentType("text/html;charset =utf-8"); //获取字符输出流输出html信息 response.getWriter().println(" <h1>Hello Servlet</h1>") } } 

 5.编译Servlet,须要依赖servlet-api.jar⽂件,将它添加
classpath

javac -cp d:\servlet-api.jar; HelloServlet.java 

6.将编译后的HelloServlet.class⽂件剪切到classes
录中

7.WEB-INF⽬录下建立并编辑web.xml⽂件,为
servlet配置请求映射

 

<?xml version="1.0" encoding="utf-8"?> <!-- 配置根节点 --> <web-app> <!-- 配置servlet类 --> <servlet> <!-- 指定servlet的别名 --> <servlet-name>hello</servlet-name> <!-- 指定Servlet的完整类名--> <servlet-class>HelloServlet</servletclass> </servlet> <!-- 配置请求映射--> <servlet-mapping> <!-- 这⾥的servlet-name和上⾯的 servlet-name要⼀⼀对应 --> <servlet-name>hello</servlet-name> <!-- 配置请求映射的url,必须以“/”开头--> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> 

 8.将项⽬部署都tomcatwebapps⽬录中,并执⾏bin
录下的startup.bat启动容器

9.打开浏览器,在地址栏输⼊http://localhost:8080/m
yweb/hello访问Servlet

4.3 Servlet的请求处理流程

浏览器发起http的请求,这个请求⾸先会被servlet容器
Tomcat)截获,而后容器会根据web.xml⽂件中配
servlet的来找到相应的这个别名,而后再根据这个
别名找到具体Servlet的类,而后容器会建立这个
Servlet类的实例并调⽤service⽅法来处理这个请求。

4.4 Servlet的⽣命周期

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


4.4.1 Servlet对象建立的过程

当第⼀次请求某个Servlet的时候,容器会先查找以前
有没有建立过这个Servlet的实例,若是没有则建立⼀
个并缓存起来。后续相同的请求都由这个缓存的对象来
处理。(注意:这⾥说的是第⼀次请求时建立。另外⼀
种状况则是在容器启动的时候就建立Servlet的实例,

4.4.2 ⽣命周期⽅法

⽅法名  描述
init Servlet对象建立以后⽴即执⾏的初始化
⽅法,且只执⾏⼀次
service 核⼼的请求处理⽅法,这个⽅法能够执⾏
屡次
destroy 容器准备销毁Servlet实例以前执⾏这个⽅
法,也是执⾏⼀次

 


 

 

 

 

 

 

 

web.xml中为Servlet指定配置,这个配置的值是⼀个整型,数值越⼩,则初始化的优先级别越⾼)

4.5 HTTP报⽂组成

4.5.1 请求报⽂

请求⾏:请求报⽂的第⼀⾏就是请求⾏。包括请求⽅
法、请求URL地址、 HTTP协议版本。
请求头:请求⾏以后的信息就是请求头,它是以名称:
内容的格式体现。主要包括服务器主机地址及端⼝、
链接状态、系统信息、编码、语⾔等等。
请求体:请求头结束以后会有⼀个空⾏,空⾏以后就是
请求体的内容。一般使⽤POST提交的数据信息会存放
在请求体当中,而后传递给服务器。
4.5.2 响应报⽂

状态⾏:主要包括HTTP协议、响应状态码(例如:
200表示OK,成功响应)。
响应头:主要包括服务器信息、响应的类型及编码、内容的⻓度、响应的时间等。
响应体:服务端能够将信息数据携带到响应体中,带回客户端。
4.6 HTTP请求⽅法

HTTP/1.1协议中,请求⽅法主要包括8个,下⾯列举
常⽤的请求⽅法进⾏说明。

⽅法 说明
GET 向服务器请求指定的资源,并返回响应主
体。⼀般来讲GET⽅法应该只⽤于数据的
读取(相似于查询)
POST 向指定的服务器提交数据(例如:表单数
据的提交、⽂件上传等) ,而且提交的数据
会放⼊请求体中(相似于新增)
PUT 向服务器提交数据,可是和POST有所区
别。若是服务器不存在此资源的时候,则
执⾏新增,若是存在则执⾏修改(相似于
修改)
DELETE 根据uri的标识删除服务器上的某个资源
(相似于删除)
其余 ...


 

 

 

 

 

 

 

 

 

 

 

 

 

 



备注: GETPOST区别:                

 


1.GET主要⽤于获取数据, POST⽤于提交数据。
2.GET请求所带的参数是放在请求⾏的url地址后⾯,⽽POST这是放在请求体中。
3.一般浏览器会对GET请求的url⻓度有所限制,⽽POST提交的数据在请求体中,能够提交更多的内容。

⽅法 说明
service 能够处理任何的请求类型
doGet 处理对应的GET请求
doPost 处理对应的POST请求
doPut 处理对应的PUT请求
doDelete 处理对应的DELETE请求
其余 ...

 

 

 

 

 

 

 

 

 

 


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

说明:经过HttpServlet的源代码得知,默认的全部请求都会先通过service⽅法,而后service⽅法根据请求
的⽅法类型判断来决定交给doGet或者是doPost⽅法来处理请求。若是⼦类重写了⽗类的service⽅法同时
还重写了其余的doXxx的⽅法,那么只有service⽅法会处理请求,其余⽅法将失效。
4.8 RequestResponse对象

web容器调⽤某个ServletService⽅法时,会建立⼀个HttpServletRequestHttpServletRespinse对象
做为参数传⼊到这个⽅法中,那么咱们能够经过HttpServletRequest来获取相关的请求内容等,⽽响应客户端

能够利⽤HttpServletResponse对象来完成。

 4.9 Servlet之间的通讯

4.9.1转发

所谓转发就是在多个Servlet之间共享请求和响应对象,全部参与转发的过程的Servlet均可以获取同一个请求对象的信息。

在servlet的API中,转发的操做有HttpServletRequest

示例代码:

 

 

package edu.nf.ch06.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletA extends HttpServlet{ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ System.out.println("请求通过ServletA,准备转发给ServletB..."); //获取页面提交的参数 String name = request.getParameter("userName"); System.out.println("ServletA获取请求参数:"+name); //可使用请求做用域(requestScope)而外携带一些数据到ServletB request.setAttribute("age", 35); System.out.println("设置请求做用域:age = " + 35); //转发由HttpServletRequest完成 //第一步先获取一个请求转发器RequestDispatcher //获取请求转发器的同时要告诉转发器转发到哪里,转发给谁 //若是要转发给ServletB,那么就是对应ServletB的url-pattern RequestDispatcher rd = request.getRequestDispatcher("servletB"); //调用转发器的forward方法执行转发,同时将request和response对象一并转发ServletB rd.forward(request, response); } } 

 

 

package edu.nf.ch06.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletB extends HttpServlet{ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("请求到达ServletB,并接收了同一个请求和响应对象"); //这里在同一个请求中再次获取页面的参数 String name = request.getParameter("userName"); //从请求做用域中取出相应的值 Integer age = (Integer)request.getAttribute("age"); System.out.println("ServletB获取请求参数:"+name); System.out.println("ServletB获取请求做用域的值:"+age); } } 

 

 <servlet> <servlet-name>servletA</servlet-name> <servlet-class>edu.nf.ch06.servlet.ServletA</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletA</servlet-name> <url-pattern>/servletA</url-pattern> </servlet-mapping> <servlet> <servlet-name>servletB</servlet-name> <servlet-class>edu.nf.ch06.servlet.ServletB</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletB</servlet-name> <url-pattern>/servletB</url-pattern> </servlet-mapping> 

 

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <a href="servletA?userName=wangl">测试转发</a><br/> </body> </html> 

 

转发的特色:

一、url的地址栏是不会发生改变的

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

4.9.2 重定向

重定向的机制和转发不一样,一次重定向的过程当中会有两次请求和两次响应,服务器在接受第一次请求后悔先作一次302响应(302表示重定向状态码)

告诉客户端浏览器必须发起一个新的请求地址,服务端再次接受这个请求处理,最后再次响应到客户端。因为会产生不一样的响应对象,所以并不一样共享同一个请求的参数

 

 

重定向是服务器通知浏览器去访问另外一个地址,即再发出另外一个请求。

下面用一张图来简单描述下:

 

重定向的特色:

一、URL地址栏会发生改变

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

示例代码:

 

package edu.nf.ch06.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletC extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("请求到达ServletC"); System.out.println("ServletC获取请求参数:"+request.getParameter("userName")); //执行重定向 //方式一:设置302响应状态码,并在响应头中添加location属性指定重定向的地址 //response.setStatus(302); //response.addHeader("location", "http://localhost:8080/ch06/servletD"); //方式二: response.sendRedirect("servletD"); } } 

 

package edu.nf.ch06.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletD extends HttpServlet{ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("重定向到ServletD"); System.out.println("ServletD获取请求参数:"+request.getParameter("userName")); } } 

 

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <a href="servletC?userName=wangl">测试重定向</a> </body> </html> 

 

4.10会话跟踪

因为HTTP协议是无状态的,服务器并不会记录每个客服端的状态,所以,若是想要实现服务器能记录客服端的状态的话,那么就须要会话跟踪技术

4.1.1cookie

cookie是客服端浏览器内部的一个文本文件,专门用于记录服务器发送过来的一些文本信息,那么再次请求的时候,都把这个cookie信息由提交回给

相应的服务器,那么服务器就能够获取客服端保存的信息,达到会话跟踪的目的,使用cookie的机制是基于客户端浏览器来维护与服务端的状态跟踪

cookie的生命周期:

示例代码:

 

默认cookie只会保存在浏览器进程的内存中,并不会写入cookie文件,若是关闭了浏览器,那么浏览器的进程也就会消失,那么对应的内存就会释放空间,

所以cookie也就销毁。若是想要cookie写入文件,那么就必须设置cookie的生命时长,一旦设置了生命时长,那么就表示这个cookie会在文件中保留多长

时间,到了这个时间以后,浏览器就会自动销毁这个cookie

设置cookie:

 

public class SetCookieServlet extends HttpServlet{ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //建立⼀个Cookie的实例 Cookie cookie = new Cookie("userId","10001"); //将cookie对象设置到响应对象中 response.addCookie(cookie); System.out.println("成功设置 cookie"); } } 

 

获取cookie

public class GetCookieServlet extends HttpServlet{ @Override protected void service(HttpServletRequest request, HttpServletResponse repsonse) throws ServletException, 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的存活时间:

示例代码:

 

//设置为0表示⽴即删除cookie cookie.setMaxAge(0); //设置为正数表示cookie在cookie⽂件的存活时间, 单位:秒 cookie.setMaxAge(5); //设置为-1表示cookie只保留在浏览器器的进程中, 关闭浏览器以后会销毁cookie cookie.setMaxAge(-1); 

 

4.4.2 Session

Session是基于服务端来保存用户的信息,这个是和cookie最大的区别。不一样的客服端在请求的服务器的时候,服务器会为每个客服端建立一个

Session对象并保存在服务器端,Session对象是每个客服端所独有的,相互之间不能访问。服务器为了区别不一样的Session属于哪个客户端,所以Session

对象也有一个惟一标识,叫作SessionID.而这个SessionID是以cookie的机制保存在客户端浏览器。每次请求的时候,浏览器都会把这个SessionID带回服务端,服务端

根据这个SessionID就能够找到对应的Session对象

示例代码:

 

public class SessionServlet extends HttpServlet{ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, 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的生命周期:Session是保存在浏览器的cookie中,可是不会写入cookie文件中,这也就是表示当关闭浏览器以后,Sessionid就会销毁,Sessionid销毁以后,服务端

的Session就没有如何做用了,可是,服务器并不会马上销毁这个Session对象,至于何时销毁是由服务器本身决定的,除非咱们手动调用了Session.invalidate()

方法,服务器就会马上销毁这个session实例

例如:

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

二、Session默认也有存活时间,服务器建立session的时候,session设置默认的存活时间为30分钟,若是在30分钟以内,

客户端没有发起任何请求到服务器来到服务器,那么服务器就会销毁这个Session对象,咱们也能够设置Session的存活时间,

能够为当前的Session设置,也能够为全局(服务端全部的Session)的Session设置

设置当前的Session的超时(存活)时间:

 

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

 

设置全局的Session存活时间:

web.xml中进⾏设置 :

 

<!-- 设置全局Session的存活时间,单位:分钟 --> <session-config> <session-timeout>60</session-timeout> </session-config>

 

Session的做用域:

当咱们须要一些数据信息出入Session的时候,就须要操做Session做用域(SessionScope),它和请求做用域相似,也有相应的setAttribute和getAttribute

的方法,只不过Session做用域的范围要比请求做用域更宽,请求的做用域在一次请求响应以后,就会消失,(由于响应以后请求对象就会销毁)。而Session

对象只要浏览器不关闭或者Session对象会一直驻留在服务器端,所以无论从新请求多少次仍是转发和重定向,均可以重Session中获取以前保存的数据信息

代码示例:

 

User user = new User(); user.setUid("1001"); user.setUserName("wangl"); HttpSession session = request.getSession(); //将数据保存在会话做⽤域中 session.setAttribute("user", user);

重回复做用域中取值:

 

HttpSession session = request.getSession(); //取值 User user = (Object)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;jsess ionid=6F1BA8C92D7E5D7CC479ED8DD30D3ED0

 

4.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提供的一个共享内存区域,能够将须要的数据信息保存在做用域中。这个做用域的的范围是最大的,只要容器没有中止,它就会一直存在。

三种做用域:

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

范围从小到大来划分:

请求做用域>会话做用域>上下文做用域

4.12 过滤器

过滤器能够在请求到达servlet以前和servlet响应客户端以前进行拦截,至关于一个拦截器

主要用于进行一些请求和响应的预处理操做,一般用的场景有限制权限的控制、统一字符编码

4.12.1编写过滤器

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

示例代码:

public class DemoFilter implements Filter { ... }

 

web.xml配置过滤器:
<filter> <filter-name>demoFilter</filter-name> <filter-class>edu.nf.ch09.filter.DemoFilter</filter-class> <!-- 初始化参数 --> <init-param> <param-name>param</param-name> <param-value>hello</param-value> </init-param> </filter> <filter-mapping> <filter-name>demoFilter</filter-name> <!-- 什么请求能够通过此过滤器,/*表示全部请求 --> <url-pattern>/*</url-pattern> </filter-mapping>

 4.12.2过滤器的生命周期

与servlet相似,Filter一样也是容器负责建立和销毁,与servlet的区别在于,容器会在启动的时候最早建立全部

的顾虑器,并执行init方法进行初始化

生命周期的方法:

方法 说明
init 初始化方法,容器启动时执行一次
doFilter 请求过滤方法,决定请求是否放行
destroy 容器销毁过滤器以前执行的方法
 
 
 
 
 
 
 
 
 


 
 
 
实例代码:
public class DemoFilter implements Filter{ @Override public void destroy() { System.out.println("准备销毁DemoFilter"); }
 @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //FilterChain表示一个过滤链对象,由于过滤器可能会存在多个 //同时这个对象将决定是否放行当前请求, //放行的话则请求会继续到达下一个过滤器或者servlet中 System.out.println("请求通过DemoFileer..放行"); chain.doFilter(request, response); System.out.println("响应前通过DemoFilter..."); } @Override public void init(FilterConfig config) throws ServletException { String name = config.getInitParameter("param"); System.out.println("初始化DemoFilter,获取初始化参数:"+name); } }

4.12.3 过滤链

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

配置示例:

<!-- 按前后顺序配置 --> <!-- 配置第一个过滤器 --> <filter> <filter-name>firstFilter</filter-name> <filter-class>edu.nf.ch09.filter.FirstFilter</filter-class> </filter> <filter-mapping> <filter-name>firstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置第二个过滤器--> <filter> <filter-name>secondFilter</filter-name> <filter-class>edu.nf.ch09.filter.SecondFilter</filter-class> </filter> <filter-mapping> <filter-name>secondFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

 

 

4.13 监听器

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

4.13.1 监听做做用域对象的建立与销毁

监听器 说明
ServletRequestListener 监听请求对象的建立和销毁
HttpSesisonListener 监听会话对象的建立和销毁
ServletContextListener 监听Servlet上下文对象的建立和销毁
 
 
 
 
 
 
 
 

 

1.请求对象监听器

public class DemoRequestListener implements ServletRequestListener{ /** * 当请求对象销毁后容器执行此方法 * 销毁方法中一样也有一个ServletRequestEvent事件对象 */ @Override public void requestDestroyed(ServletRequestEvent event) { //经过这个事件对象就能够获取当前的请求对象 HttpServletRequest request = (HttpServletRequest)event.getServletRequest(); System.out.println("销毁请求对象..."+request); } /** * 当请求对象建立以后容器调用此方法 * ServletRequestEvent这个参数就是一个事件对象 */ @Override public void requestInitialized(ServletRequestEvent event) { //经过这个事件对象就能够获取当前的请求对象 HttpServletRequest request = (HttpServletRequest)event.getServletRequest(); System.out.println("初始化了请求对象..."+request); } }

 

 
web.xml配置
<!-- 配置监听器 --> <listener> <!-- 指定监听器的完整类名 --> <listener-class>edu.nf.ch10.listener.DemoRequestListener</listener-class> </listener>

 

 
二、会话监听器
public class DemoSessionListener implements HttpSessionListener{ /** * 监听HttpSession对象的建立 * HttpSessionEvent参数是一个事件对象 * 经过它能够得到当前的HttpSession */ @Override public void sessionCreated(HttpSessionEvent event) { HttpSession session = event.getSession(); System.out.println("建立了Session对象"+session); } /** * 监听HttpSession对象的销毁 */ @Override public void sessionDestroyed(HttpSessionEvent event) { HttpSession session = event.getSession(); System.out.println("销毁了Session对象"+session); } }

 

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

web.xml配置

<listener> <!-- 指定监听器的完整类名 --> <listener-class>edu.nf.ch10.listener.DemoSessionListener</listener-class> </listener>

 

3.Servlet上下文监听器
public class DemoContextListener implements ServletContextListener{ /** * 监听ServletContext的销毁 */ @Override public void contextDestroyed(ServletContextEvent event) { //经过事件对象获取ServletContext ServletContext sc = event.getServletContext(); System.out.println("销毁了ServletContext对象..."+sc); } /** * 监听SerlvetContext的建立 */ @Override public void contextInitialized(ServletContextEvent event) { //经过事件对象获取ServletContext ServletContext sc = event.getServletContext(); System.out.println("建立了ServletContext对象..."+sc); } }

 

配置web.xml
<listener> <!-- 指定监听器的完整类名 --> <listener-class>edu.nf.ch10.listener.DemoContextListener</listener-class> </listener>

 4.13.2 监听做用域的操做

监听器 说明
ServletRequestAttributeListener 监听请求做用域的操做
HttpSessionAttributeListener 监听会话做用域的操做
ServletContextAttributeListener 监听Servlet上下文做用域的操做

 

 

 

 

 

 

 

示例代码:这里以HttpSessionAttributeListener说明,其余做用于监听器用法类似。

public class DemoSessionAttributeListener implements HttpSessionAttributeListener{ /** * 当有数据添加到会话做用域时,执行此方法 */ @Override public void attributeAdded(HttpSessionBindingEvent event) { //获取存入做用域的键和值 System.out.println("存入会话做用域..."+event.getName() + " : " + event.getValue()); } /** * 当从会话做用域移除数据时,执行此方法 */ @Override public void attributeRemoved(HttpSessionBindingEvent event) { System.out.println("移除会话做用域..."+event.getName() + " : " + event.getValue()); } /** * 当替换了会话做用域中的某个数据时,执行此方法 */ @Override public void attributeReplaced(HttpSessionBindingEvent event) { HttpSession session = event.getSession(); //从session中获取的是替换以后的值 System.out.println("替换的值: "+session.getAttribute("userName").toString()); //注意:这里event.getValue()获取到的是替换以前的值 System.out.println("替换会话做用域..."+event.getName() + " : " + event.getValue()); } }

 

 web.xml 配置

<listener> <!-- 指定监听器的完整类名 --> <listener-class>edu.nf.ch10.listener.DemoSessionAttributeListener</listener-class> </listener>

4.14 注解配置

Servlet3.0开始提供了一系列的注解来配置Servlet、Fiilter、Listener等等。这种方式能够极大的简化在开发中大量的xml的配置。

从这个版本开始,web.xml能够再也不须要,使用相关的注解一样能够完成相应的配置。彻底配置,

 

注解 说明
@WebServlet 这个注解标识在类上,用于配置Servlet。例如:@WebServlet(name="hello", urlPatterns="/hello") 也可简化配置@WebServlet("/hello")
@WebFilter 这个注解标识在类上,用于配置Filter。例如:@WebFilter(filterName="encode",urlPatterns="/") 也可简化配置@WebFilter("/"),
@WebListener 这个注解标识在类上,用于配置监听器

 

 
 
 
 
 
 
 
 
 
 
 
 

5. JSP基础

5.1 简介

JSP全名为java Server Pages,中文名叫java服务器页面,是一种动态页面技术,而HTML是属于静态页面。JSP

能够在HTML中嵌入java脚本代码,由于JSP本质上仍是一个Servlet,所以JSP也必须依赖于web容器才能运行

JSP的出现并非为了去掉Servlet,而是简化了Servlet的工做,将Servlet中繁琐的视图呈现代码脱离出来,交给

JSP来完成,让Servlet专一于请求的处理,全部在开发中一般将jsp和Servlet结合一块儿使用

5.2JSP引擎

因为JSP本质上就是一个Servlet,那么JSP文件转义成一个Servlet的java源文件,而后经过javac将这个源文件编译成class

字节码文件并装载到JVM中执行,JSP引擎的核心类是JSPServlet,位于Jasper.jar文件张总,而且在Tomcat的web

.xml中也默认就配置好了这个类(JSPServlet也是一个servlet,所以凡是以“.jsp”结尾的请求都会先通过JSPServlet

,那么这个引擎就能够开始工做了。一般引擎转义和编译后的文件放在容器的work工做目录中)

注意:若是第一次访问jsp文件的时候,因为work目录中并不存在源文件和字节码文件,jsp引擎就必须完成这两个工做,

所以,有可能在第一次访问jsp时会比较缓慢,当字节码编译出来加载后,第二次访问时的速度就会很快了

5.3JSP的三大元素

语法:<%@  %>

指令 说明
page指令 用于设置JSP页面的相关信息以及编码
include指令 用于静态包含其余的JSP页面代码,所谓静态包含,就是在编译期,将另外的JSP页面的代码合并到当前的JSP中,最终只会产生一个Java源文件
taglib指令 这个指令用于引入标签库
 
 
 
 
 
 
 
 
 

5.3.2 动做元素

语法:jsp:xxx

动做 说明
include 动态包含其余JSP页面的内容,所谓的动态包含是指在编译期将不一样的JSP文件转义成不一样的Java源文件,而后在运行时才将目标内容包含到当前的JSP页面中
forward 至关于Servlet中的转发,转发到其余的JSP页面或者Servlet
param 用于传递参数,一般结合其余的动做一块儿使用,例如转发时须要提交一些而外的参数
useBean 用于在JSP页面中使用JavaBean对象,一般结合setProperty和getProperty来使用,完成bean对象的赋值和取值操做
 
 
 
 
 
 
 
 





5.3.3 脚本元素          

脚本元素主要就是在JSP中嵌入Java脚本代码,包括声明、表达式、Java脚本

声明语法:<%! %>

表达式: <%= %>

Java脚本: <% %>

代码实例:

<%@ 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>Insert title here</title> </head> <body> <%-- 声明变量和方法,这里声明的变量a是实例变量 --%> <%! int a = 10; public void say(){ System.out.println("hello"); } %> <%-- 表达式,注意:表达式后面是不容许有;号结束的 --%> 3 + 1 = <%=3+1%><br/> <%-- Java脚本,脚本代码最终会生成在servlet中的service方法中做为代码片断 --%> <table border="1"> <tr> <th>Name</th> <th>Age</th> </tr> <% for(int i=0;i<5;i++){%> <tr> <td>user<%=i%></td> <td><%=10+i%></td> </tr> <%}%> </table> </body> </html>

 

 

5.4 JSP内置对象

内置对象,是在容器运行时将建立好的9个对象内嵌在JSP中,在JSP里能够直接拿来使用的对象

对象 说明
out 字符流输出对象
config 等同于Servlet中的ServletConfig
page 表示当前JSP页面
request 等同于Servlet中的HttpServletRequest
response 等同于Servlet中的HttpServletResponse
session 等同于Servlet中的HttpSession
application 等同于Servlet中的ServletContext
pageContext 表示当前JSP页面的上下文对象
exception 表示当前JSP中的异常对象
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<%@ 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>Insert title here</title> </head> <body> <%-- 经常使用内置对象 --%> <% //使用request,API使用同HttpServletRequest同样 request.getParameter("userName"); request.setAttribute("user", "user1"); request.getAttribute("user"); //使用session,API使用等同于HttpSession session.setAttribute("user", "user2"); session.getAttribute("user"); session.getId(); //使用response //response.sendRedirect("demo.jsp"); //out对象,等同于字符输出流对象,在JSP页面输出相关内容 out.println("hello world"); //这个是输出在控制中 System.out.println("hello"); //使用application,等同于ServletContext application.setAttribute("userName", "user3"); //pageContext使用 //从pageContext中获取相关的其余对象 HttpServletRequest req = (HttpServletRequest)pageContext.getRequest(); HttpServletResponse res = (HttpServletResponse)pageContext.getResponse(); HttpSession ses = pageContext.getSession(); ServletConfig conf = pageContext.getServletConfig(); ServletContext sc = pageContext.getServletContext(); //也能够经过pageContext来统一设置不一样的做用域 //第三个参数表示要放入到哪一个做用域,是一个int类型的参数 //1表明page做用域(当前页面有效) //2表明请求做用域 //3表明会话做用域 //4表明上下文做用域 pageContext.setAttribute("userName", "zhangsan", 2); //也能够指定中哪一个做用域取出相应的值 String name = (String)pageContext.getAttribute("userName", 2); out.println(name); %> </body> </html>

 

5.5 EL表达式

EL(Expression Language),全称叫作表达式语言,是JSP2.0推出的一种技术。主要简化了在JSP中使用Java脚本表达式。EL表达式的特色在于使用简单,支持四则运算、逻辑运算等,而且还能够对Servlet API中的对象进行数据访问。EL的语法: ${expression}

运算:

示例 结果
${1+1} 2
${2*2} 4
${1==1} true
${2>5} false
其余 ...

 

 

 

 

 

 

 



数据访问:

1.使用“.”来访问

示例 说明
${param.参数名} 获取请求参数的值,至关于使用request.getParameter()方法
${requestScope.xxx} 从请求做用域中访问数据
${sessionScope.xxx} 从会话做用域中访问数据
${applicationScope.xxx} 从上下文做用域中访问数据
${xxx} 不指定做用域范围时,默认按照做用域范围从小到大的顺序自动查找
其余 ...

 

 

 

 

 

 

 
 







2.使用"[]"来访问
示例 说明
${requestScope[“userName”]} 从请求做用域中取值
${sessionScope[“userName”]} 从会话做用域取值
其余... 同上
 
 
 
 
 
 
 
 
 
 


注意:一般使用"[]"来访问数据的时候,主要是访问一些特殊的名称,例如:request.setAttribute("user.userName")

这种方式若是使用${requestScope.user.userName}是访问不到的,应该改成

${requestScope["user.userName"]}来访问

5.6 JSTL核心标签库

JSTL是JSP中的标准标签库,主要用于取代JSP中大量的Java脚本代码,让页面看起来更趋向于HTML。使用也很简单,一般结合EL表达式一块儿使用

示例:

核心标签库(core) 说明
c:out 输出标签
c:set 声明某个变量并存入指定的做用域
c:redirect 重定向标签
c:if 条件判断
c:forEach 循环标签
其余 ...
 
 
 
 
 
 
 
 
 
 
 





备注:其余标签库请参阅相关官方文档
 
 
 
 
 
 

 5.3.

相关文章
相关标签/搜索