1、WEB概述
- C/S是指客户端(Client)/服务器(Server)模式。B/S是指浏览器(Browers)/服务器(Server)模式。
- WEB特征
信息的表达——采用HTML来表达和建立信息之间的链接
信息的定位——用统一资源定位技术URL来实现网络信息的精确定位
信息的传输——用网络应用层协议HTTP来规范浏览器和Web服务器之间的通信过程 - URL一般由3个部分组成:
应用层协议
主机IP地址或域名
资源所在路径/文件名
应用层协议://主机IP地址或域名/资源所在路径/文件名
http://www.javathinker.org:80/java/book.htm
- HTTP请求由3个部分构成,分别是:
请求方法、URI和HTTP协议的版本
请求头(Request Header)
请求正文(Request Content) - HTTP响应由3个部分构成,分别是:
HTTP协议的版本、状态代码和描述
响应头(Response Header)
响应正文(Response Content) HTTP协议规定,请求头和请求正文、响应头和响应正文之间必须以空行分隔,这个空行非常重要,表示请求头已经结束,接下来是请求正文。
- 状态码
1**:信息提示,表示临时的响应
2**:响应成功,表明服务器成功地接收了客户端请求
3**:为完成请求,客户需要进一步细化
4**:客户端错误,表明客户端可能有问题
5**:服务器错误,表明服务器由于遇到某种错误而不能响应客户端请求
2、Servlet
- servlet基本功能
动态生成HTML文档
把请求转发给同一个Web应用中的其他Servlet组件
把请求转发给其他Web应用的Servlet组件
读取客户端的Cookie,以及向客户端写入Cookie
访问其他服务器资源(数据库或基于Java的应用程序) - servlet5个接口
init(ServletConfig config)方法
:负责初始化Servlet对象,容器在创建好Servlet对象后并在Servlet能为客户请求提供服务之前就会调用该方法。
Service(ServletRequest req,ServletResponse res)方法
:负责响应客户的请求,为客户提供相应服务。当容器接收到客户端要求访问特定Servlet对象的请求时,就会调用该Servlet对象的service()方法。
destory()方法
:负责释放Servlet对象占用的资源,当Servlet对象结束生命周期时就会调用该方法。
getServletConfig ()方法
:返回一个ServerConfig对象,在该对象中包含了Servlet的初始化参数信息。
getServiceInfo()方法
:返回一个字符串,在该字符串中包含了Servlet的创始者、版本和版权等信息。
- GenericServlet抽象类
实现了Servlet接口中的init方法,并且使得自己与一个ServletConfig对象关联。
没有实现Servlet接口中的serivce方法,是这个类中唯一的一个抽象方法。
实现了Servlet接口中的destroy方法,但是实际上什么都没有做。 - HttpServlet抽象类
HttpServlet类实现了Servlet接口中的
Service(ServletRequest req,SerletResponse res)
方法,该方法实际上调用了它的重载方法Service(HttpServletRequest req, HttpServletResponse resp)
。在此方法中,首先调用了HttpServletRequest
类型的req参数getMethod()
方法,从而获得客户端请求方式,然后根据方式来调用匹配的服务。
假定HelloServlet类是HttpServlet类的子类,如果客户端只按照GET方法请求访问HelloServlet ,那么只需要重新实现doGet()
方法。
- JAVA WEB应用的生命周期
启动阶段
(1)把web.xml文件中的数据加载到内存中
(2)为JavaWeb应用创建一个ServletContext对象
(3)对所有的Filter进行初始化
(4)对那些在Web应用启动时就被初始化的Servlet进
行初始化
运行的阶段
在这个阶段,它所有Servlet都处于待命状态,随时可以响应客户端的特定请求,提供相应的服务。假如客户端请求的Servlet还不存在,Servlet容器会先调用它的inti()方法初始化Servlet,然后再调用它的Service()服务方法。
终止阶段
(1)销毁JavaWeb应用中所有处于运行时状态的Servlet
(2)销毁JavaWeb应用中所有处于运行时状态的Filter
(3)销毁所有与JavaWeb应用相关的对象。如ServletContext对象等,并且释放Web应用所占用的相关资源。 - Servlet的生命周期:
init()初始化阶段
、service()运行时阶段
和destory()销毁阶段
初始化阶段
1、Servlet容器加载Servlet类,把它的.class文件中的数据读入到内存中
2、Servlet容器创建ServletConfig对象。ServletConfig对象包含了特定Servlet的初始化配置信息,如Servlet初始参数。此外,Servlet容器还会使得ServletConfig对象与当前Web应用对的ServletContext对象关联。
3、 Servlet容器创建Servlet对象
4.、Servelt容器调用init(ServeltCofig config)方法。以上初始化步骤创建了Servlet对象和ServletConfig对象,并且建立两者之间的关联,而ServletConfig对象又与当前Web应用的ServletContext对象关联。当Servlet容器初始化完Servlet后,Servlet对象只要通过getServeltContext()方法就能得到当前Web应用的ServletContext对象。
运行的阶段
在这个阶段,Servlet可以随时响应客户端的请求。当Servlet容器接收到要求访问特定Servlet客户端请求时,Servlet容器会创建针对这个请求的ServletRequest对象和ServletResponse对象,然后调用相应Servlet对象的service()方法。当Servlet容器把Servlet生成的响应结果发送给了客户,Servelt容器就会销毁ServletRequest对象和ServletResponse对象。
销毁阶段
当Web应用被终止时,Servlet容器会先调用Web应用中所有Servlet对象destory()方法,然后再销毁这些Servlet对象。在destory()方法的实现中,可以释放Servlet所占用的资源(例如关闭文件输入流和输出流,关闭与数据库的连接).此外,容器会销毁Servlet对象关联的ServeltConfig对象。
- 自动加载Servlet程序
<load-on-startup>
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-class>Servlet1</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
- WEB.xml设置初始化参数
<init-param>
是配置在<servlet>
标签里,只能由这个Servlet来读取
<servlet>
<servlet-name>font</servlet-name>
<servlet-class>cn.FontServlet</servlet-class>
<init-param>
<param-name>color</param-name>
<param-value>blue</param-value>
</init-param>
</servlet>
//读取初始化参数
String color=getInitParameter("color");
- 上下文参数
<context-param>
<param-name>company</param-name>
<param-value>itcast</param-value>
</context-param>
// 得到ServletContext对象
ServletContext context = this.getServletContext();
// 得到包含所有初始化参数名的Enumeration对象
Enumeration<String> paramNames = context.getInitParameterNames();
// 遍历所有的初始化参数名,得到相应的参数值
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = context.getInitParameter(name);
}
- 资源注射
<env-entry>
<env-entry-name>helloInject</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Hello,Welcome to the JavaEE Resource Injection.</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>iInject</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>30</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>personsInject</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Helloween,Cobain,Roses,Axl</env-entry-value>
</env-entry>
// 注入的 字符串
private @Resource(name="helloInject")
String hello;
// 注入的 整数
private @Resource(name="iInject") int i;
// 注入更常见的写法
@Resource(name="personsInject")
private String persons;
- 多个Servlet共享数据
Enumeration getAttributeNames()
、Object getAttribute(String name)
、void removeAttribute(String name)
、void setAttribute(String name,Object obj)
读取WEB应用下的资源文件
Set getResourcePaths(String path)
,String getRealPath(String path)
,URL getResource(String path)
,InputStream getResourceAsStream(String path)
ServletContextListener接口
监听context的创建与销毁。服务器启动或者热部署war包时执行contextInitialized
方法,服务器关闭时或者只关闭该Web时会执行contextDestroyed
方法。这个监听器一般用来启动时获web.xml
里配置的初始化参数。HttpServletResponse接口
getOutputStream()
想输出二进制格式的响应正文,就需要使用getOutputStream()方法
getWriter()
想输出内容全为字符文本的网页文档,需要使用getWriter()方法
虽然response对象的getOutputStream()和getWriter()方法都可以发送响应消息体,但是,它们之间互相排斥,不可同时使用,否则会发生IllegalStateException异常。
使用response解决中文乱码问题
// 设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8");
// 通知浏览器使用utf-8解码
response.setHeader("ContentType","text/html;charset=utf-8");
// 第三种方式
response.setContentType("text/html;charset=utf-8");
网页定时刷新并跳转
response.setHeader("Refresh","3");
response.setHeader("Refresh","3;URL=http://localhost:8080");
请求重定向
response.sendRedirect("/Servlet/login.html");
防止页面被客户端缓存
//使用HTTP1.0的浏览器
Response.addHeader("progma","no-cache");
//使用HTTP1.1的浏览器
response.setHeader("Cache-control","no-cache");
- HttpServletRequest接口
获取请求参数
String getParameter(String name)
,String[] getParameterValues(String name)
请求参数中文乱码问题 post
request.setCharacterEncoding(String encode)
通过request对象传递数据
setAttribute()
方法、getAttribute()
方法、removeAttribute
方法、getAttributeNames
方法 - WEB组件之间协作的几种关系
请求转发
、重定向
、包含
、链接
- 转发:源组件与目标组件共享请求范围内的数据。源组件不允许向客户提交响应结果。
由于forward()方法先清空用于存放响应正文数据的缓冲区,因此Servlet源组件生成的响应结果不会被发送到客户端,只有目标组件生成的响应结果才会发送到客户端。
如果源组件在进行请求转发之前已经提交了响应结果,那么forward()方法会抛出IllegalStateException。因此不应该在源组件中提交响应结果。
- 包含:源组件与目标组件协作完成对同一个客户请求的响应,源组件与目标组件共享请求范围内的数据。响应结果是由源组件与目标组件共同产生的。
源组件与被包含的目标组件的输出数据都会添加到响应结果中
在目标组件中对应响应状态代码或者响应头所做的修改都会被忽略
3、会话及其会话技术
- WEB服务器跟踪客户状态的四种方式
在HTML表单中加入隐藏字段,它包含用户跟踪客户状态的数据
用Cookies来传送用于跟踪客户状态的数据
使用会话(Session)机制
重写URL,使它用于跟踪客户状态的数据
- 当客户第一次访问JSP页面时,JSP容器会自动创建一个session对象,用来存储客户在访问各个页面提交的各种信息,一个session对应一个客户。同时被创建的session被分配一个ID号,tomcat把这个ID号保存在客户端的cookie中,这样session就和客户之间建立对应关系。
- Cookie是一种会话技术,它用于将会话过程中的数据保存到用户的浏览器中,从而使浏览器和服务器可以更好地进行数据交互。
- Cookie常用方法
- 同一个服务器下的app共享Cookie
Cookie cookie = new Cookie("username",Tom);
cookie.setPath("/");
response.addCookie(cookie);
以上setPath的参数为“/”,表示Tomcat服务器A的根路径,因此同一个Tomcat服务器A中所有的Web应用可以共享上述Cookie。
Cookie cookie = new Cookie("username",Tom);
cookie.setPath("/app2/");
response.addCookie(cookie);
以上setPath的参数为“/app2/”,表示只有Tomcat服务器A的app2应用可以访问该Cookie,app1应用也无法访问该Cookie。
Cookie cookie = new Cookie("username",Tom);
cookie.setPath("/app1/sub/");
response.addCookie(cookie);
以上setPath的参数为“/app1/sub/”,因此只有Tomcat服务器A中的app1应用中位于的/sub子路径下的Web组件才能访问该Cookie。
Cookie cookie = new Cookie("username",Tom);
cookie.setDomain(".cat.com");
response.addCookie(cookie);
让Tomcat服务器B中所有Web应用访问Cookie,假定Tomcat服务器B的域名为”www.cat.com”。
Cookie cookie = new Cookie("username",Tom);
cookie.setDomain(".cat.com");
cookies.setPath("/app3/");
response.addCookie(cookie);
如果仅仅希望Tomcat服务器B中的app3应用能访问该Cookie
- 通常情况下,Session是借助Cookie技术来传递ID属性的
- session常用方法
- 在下面三种情况下,Servlet容器会销毁会话
浏览器进程终止
服务器执行HttpSession对象的invalidata()方法
会话过期 - 在web.xml中设置session过期时间
//单位为分钟
<session-config>
<session-timeout>30</session-timeout>
</session-config>
如果将
<session-timeout>
元素中的时间值设置成0或一个负数,则表示会话永不超时。由于<Tomcat安装目录>\conf\web.xml
文件对站点内的所有Web应用程序都起作用,因此,如果想单独设置某个Web应用程序的会话超时间隔,则需要在自己应用的web.xml
文件中进行设置。
- 把Session ID添加到URL信息中。调用
HttpServletResponse
接口的重写URL方法Public java.lang.String encodeURL(String url)
,但是要记住先通过getSession
方法获取Session。 - 标准会话管理器StandardManager
默认的会话管理器,会把Web应用对应的HTTPSession对象持久化,保存到文件系统中。默认的文件为work/Catalina/localhost/Web应用/SEESIONS.ser - PersistendManager
将HTTPSession对象持久化保存到会话Store中
具有容错功能,及时把HTTPSession对象备份到会话Store中
可以灵活控制内存中HTTPSession的数目,将部分HTTPSession对象转移到会话Store中
提供两种功能,一种是备份到文件中(FileStore),一种是保存到数据库的一张表中(JDBCStore) - 配置FileStore
在Web应用的METE-INF/context.html文件中加入<manager>
元素和<store>
元素。
<Context reloadable="true">
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="true"
maxActiveSessions="10"
minIdleSwap="60"
maxIdleSwap="120"
maxIdleBackup="180"
maxInactiveInterval="300">
<Store className="org.apache.catalina.session.FileStore" directory="mydir"/>
</Manager>
</Context>
- HTTPSessionListener接口:
sessionCreated(HttpSessionEvent event)
、sessionDestroyed(HttpSessionEven event)
- HTTPSessionAttributeListener接口:
attributeAdded(HttpSessionBindingEvent event)
,attributeRemoved(HttpSessionBindingEvent event)
,attributeRePlace(HttpSessionBindingEvent event)
- HttpSessionBindingListener:
valueBound(HttpSessionBindingEvent event)
,valueUnbound(HttpSessionBindingEvent event)
HttpSessionActivationListener:
sessionDidActive(HttpSessionEvent event)
,sessionWillPassivate(HttpSessionEvent event)
HTTPSessionAttributeListener 和HTTPSessionListener,它们必须在web.xml文件中通过
<listener>
元素向Servlet容器注册。
HttpSessionBindingListener HttpSessionActivationListener这两个Listener监听的是Session中的对象而非Session,因此不需要在web.xml中声明。4、过滤器和监听器
- 请求过滤器可以做的事情
请求过滤器是在请求还没有到达目标资源之前调用
可以在完成对ServletRequest安全检查
可以利用ServletRequestWrapper重新格式化请求首部或者是请求体的内容
建立请求审计或日志
可以压缩响应流
追加或修改响应流
创建一个完全不同的响应 - 所有自定义的过滤器都必须实javax.serlvet.Filter接口,这个接口含有3个过滤器必须实现的方法
init(FilterConfig config)
:对过滤器的初始化方法,可以通过config参数来读取web.xml文件中为过滤器配置的初始化参数.在Web应用初始化的时候加载。第一次加载的执行顺序随机,以后再次加载以第一次顺序为准。
doFileter(ServletRequest req,ServletResponse res,FileterChain chain)
:这个方法完成实际的过滤操作。当客户请求访问的URL与为过滤器映射的URL匹配时,Servlet容器先调用过滤器的doFileter()方法。按照<filter-mapping>
顺序执行。FileterChain参数用于访问后续过滤器或者Web组件。
destory()
:这个方法在Servlet容器销毁过滤器对象前调用,这个方法中可以释放过滤器占用的资源。
- 过滤器同样的也包含三个生命周期:初始阶段、运行阶段和销毁阶段
- web.xml配置filter
<filter>
<filter-name>filterName</filter-name>
<filter-class>filter.MyFilter</filter-class>
<init-param>
<param-name>paramName</param-name>
<param-value>paramValue</param-value>
</init-param>
</filter>
<filter>
规则
必须有<filter-name>
必须有<filter-class>
<init-param>
是可选的,可以有多个<init-param>
- 声明对应URL模式的过滤器映射
<filter-mapping>
<filter-name>filterName</filter-name>
<url-pattern>/jsp/*</url-pattern>
<servlet-name>myServlet</servlet-name><dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
必须有
<filter-name>
,用于链接到适当的<filter>
元素
<url-pattern>
和<servlet-name>
,可以由多个相同的元素
< url-pattern >
元素定义了请求哪些Web应用资源要使用这个过滤器
<servlet-name>
元素定义了请求哪些Servlet要使用这个过滤器
可以由0-4个元素,默认为request。通过转发、包含如用过滤器。
- JSP编译三个步骤
第一阶段会用pageEncoding:
第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8
JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。
第二阶段会用utf-8到utf-8:
JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是 JVM对常数字串在二进制码(java encoding)内表达的规范。
第三阶段就是由Tomcat出来的网页, 用的是contentType.Tomcat(或其的application
container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效
- 串联过滤器
多个过滤器可以串联起来协同工作,Sevlet容器根据他们在web.xml中定义的<filter-mappling>
先后顺序,依次调用它们的doFilter()
方法。 - 过滤器主要用来
用户认证与授权管理
统计Java Web应用的访问量和访问的命中率,形成访问报告
实现Web应用的日志处理功能
实现图像格式转换
实现数据压缩功能
对传输的数据进行加密
触发资源访问事件
实现XML文件的XSLT转换 - Listener分类-监听对象的创建于销毁
ServletContextListener
:监听context的创建与销毁。服务器启动或者热部署war包时
执行contextInitialized方法,服务器关闭时或者只关闭该Web时会执行contextDestroyed方
法。这个监听器一般用来启动时获web.xml里配置的初始化参数。
HttpSessionListener
:监听Session的创建与销毁。创建Session时执行sessionCreated方法,超时或者执行session.invalidate()时,执行sessionDestroyed方法。这个监听器一般用来收集在线者信息。
ServletRequestListener
:监听request的创建与销毁。用户每次请求request都会执行
requestInitialized方法。Request处理完毕自动销毁requestDestroyed方法。注意如果一个HTML页面内包含多个图片,则请求一次HTML页面可能会触发多次request事件。 - Listener分类-监听对象属性的变化
HttpSessionAttributeListener
,ServletContextAttributeListener
,ServletReqeustAttributeListener
分别用于监控Session、context、request的属性变化。当监听对象中添加、更新、移除属性时,会分别执行***Added(),***Replaced(),***Removed(). - Listener分类-监听session类的对象
HttpSessionBindingListener
:绑定后valueBound(HttpSessionBindingEvent event)
,解绑前valueUnbound(HttpSessionBindingEvent event)
HttpSessionActivationListener
:激活后sessionDidActive(HttpSessionEvent event)
,钝化前sessionWillPassivate(HttpSessionEvent event)
这两个Listener监听的是Session中的对象而非Session等,因此不需要在web.xml中声 明。 - 会话持久的好处:节约内存空间、确保在服务器重启或者是单个Web应用重启后,能够恢复重启前的会话。