Web快速入门
网络应用
- C/S : Client/Server(客户机/服务器)的简称,也称为胖客户端,桌面应用程序采用的多是这种结构;
- B/S : Browser/Server(浏览器/服务器)的简称,也称为瘦客户端,特点是客户端无需安装特定的软件,只需要安装一个浏览器就可以与系统进行交互;
- R|A : “Rich Internet Applications”的缩写,意为“富客户端网络应用”
- 主要目标 : 基于B/S结构,只要有浏览器就可以使用,在浏览器里实现与客户端软件类似的体验;例如:可以局部刷新、可以拖拽等;
- web站点 : Web Site,也被称为Web网站;比如某公司用来作为宣传使用的官方网站;
- web应用 : Web Application,简单来说,就是通过浏览器访问的应用程序,从而为用户提供相关的服务,例如查询、购物、生成报表等;
- HTTP服务器 : 也称为Web服务器,主要功能是提供网上信息浏览服务,例如Apache、Nginx、IIS是比较常用的HTTP服务器;使用浏览器访问Web站点或者Web应用,则必须通过HTTP服务器;
- Web应用服务器 : Web应用服务器能够运行服务器上的应用程序,并将结果返回给客户端浏览器;例如,Tomcat就是一种Web应用服务器;通常情况下,Web应用服务器兼具HTTP服务器的部分功能;
Servlet
一个Servlet类总是继承HttpServlet
Servlet配置
- 在web.xml中: 需要对Servlet配置\以及\,其中url-pattern是访问Servlet使用的逻辑地址;
<servlet> <servlet-name></servlet-name> <servlet-class></servlet-class> </servlet> <servlet-mapping> <servlet-name></servlet-name> <url-pattern></url-pattern> </servlet-mapping>
- 注解 : @WebServlet(“/xxxservlet”);
Servlet线程特性
- Servlet是运行在服务器端的组件,能够给客户端返回动态页面;
- Servlet是【多线程单实例】的
- 第一次访问Servlet时,服务器将创建一个该Servlet类的对象,并调用doXXX方法生成响应;多个客户端访问同一个Servlet时,不再创建新的对象,而是共用同一个Servlet对象;
Servlet的生命周期
- 请求Servlet后,容器会创建Servlet对象并进行初始化,调用doXXX方法响应特定的HTTP请求,不再使用时容器将销毁Servlet;
自定义Servlet类中一般写什么方法
- 自定义Servlet类中一般重写doGet或doPost方法,需要的话可以重写无参init方法进行初始化操作;
请求和响应接口
- Web应用基于HTTP协议,HTTP协议基于请求/响应模型;
客户端访问服务器端Servlet的方式有三种
- 直接从地址栏输入URL访问;
- 在网页中点击超级链接访问;
- 在网页中通过表单提交访问;
Servlet中获取请求参数的四种方法
- String getParameter(String name)
- 返回某个指定名字的请求参数的值,值为String类型;
- String[] getParameterValues(String name)
- 返回指定名字的请求参数的值,值为String[]类型,一般用于一个名字对应多个值情况;
- Map<\String,String[]> getParameterMap()
- 将所有请求参数的name和value作为键值对返回,存储在Map对象中;
- Enumeration<\String> getParameterNames()
- 返回所有的请求参数的名字,存在集合对象中;
参数
- 需要在应用下所有Servlet中都能够使用某个参数,可以定义全局参数
<context-param> <param-name>x</param-name> <param-value>y</param-value> </context-param>
- Servlet的初始化参数只能在当前Servlet中使用
<init-param> <param-name>x</param-name> <param-value>y</param-value> </init-param>
Servlet加载启动
默认情况下,只有当第一次访问Servlet时,服务器才会初始化Servlet实例;
如果需要更早实例化Servlet,可以在web.xml中进行配置,使得在启动容器的时候就能初始化Servlet实例
<!--使得在启动容器的时候就能对Servlet实例化,数字1表示的是顺序。Servlet永远只被实例化1个对象 --> <servlet> <load-on-startup>1</load-on-startup> </servlet>
Servlet配置中通配符*的用法
.扩展名: .do
以 / 开头,同时以 /* 结尾,比如 /* 、/admin/*
<servlet-mapping> <servlet-name>xxxServlet</servlet-name> <url-pattern>*.do</url-pattern> <url-pattern>/admin/*</url-pattern> </servlet-mapping>
web.xml中错误页面的配置
<!--全局错误页面配置--> <!--404错误页面 --> <error-page> <error-code>404</error-code> <location>/404.html</location> </error-page> <!--发生空指针异常并没有被处理时,跳转到excetption.html--> <error-page> <exception-type>java.lang.NullPointerException</exception-type> <location>/exception.html</location> </error-page>
Servlet中获取请求头属性的方法
- String getHeader(String name)
- 返回某个请求头属性的值,值为String类型
- Enumeration<\String> getHeaders(String name)
- 返回指定名字的请求头属性的值,值为集合类型,一般用于一个名字对应多个值情况;
- int getIntHeader(String name)
- 返回值类型是int类型的请求头属性值;
- long getDateHeader(String name)
- 返回日期类型的请求头属性值,返回long型值;
- Enumeration<\String> getHeaderNames()
- 返回所有请求头属性的名字;
JSP
JSP(Java Server Page)是JavaEE规范中的Web组件,用来编写动态页面;
JSP运行在服务器端,本质是Servlet;
JSP文件以.jsp为后缀,在Eclipse的工程目录中存在WebContent目录下;
JSP文件可以直接在浏览器中访问;
JSP文件中的内容就是 HTML+Java代码,静态部分使用HTML和文本即可,动态部分使用Java代码;
JSP的执行流程(在浏览器通过http://127.0.0.1:8080/xxxservlet/xxx.jsp访问,流程如下:) 执行流程分为:翻译–>编译–>实例化–>提供服务
- 翻译:Web服务器找到xxx.jsp,对其进行翻译,生成xxx.java文件。查看路径:
- .metadata.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost
- 编译:服务器将xxx.java编译成类文件,翻译和编译的过程遵守Servlet规范,因此说JSP的本质也是Servlet;
- 实例化并提供服务:服务器实例化类,调用类中的_jspService方法提供服务
为什么要使用JSP组件
- Servlet生成动态页面比较繁琐,使用JSP生成动态页面比较便捷,因为其中的静态内容可以使用HTML生成;
页面元素
- 脚本元素
- 格式为 : %Java代码%>
- 服务器翻译脚本元素时,将把其中Java代码直接翻译到_jspService方法中
- JSP中的Java代码都可以直接写到脚本元素中,即<%%>中
- 表达式元素
- 格式为 : <%=Java代码%>
- 服务器翻译表达式元素时,将把其中Java代码部分的返回值使用out.write语句输出
- 如果要向浏览器输出动态内容,可以使用表达式元素<%=%>
- 模板元素
- 模板元素指JSP中静态HTML或者XML内容
- 注释元素
- 格式为<%–JSP注释–%> JSP的注释只有在源代码中可见,翻译时已经忽略;
- 格式为\ HTML注释翻译时_jspService 翻译到java代码中
- 格式为//java _jspService 使用out.write()输出
- 声明元素
- 格式为 : <%! 声明语句%>
- 声明元素被翻译到Java类中,而不是_jspService方法中
- 声明元素不能用内置对象
(九大)内置对象
- 内置对象指的是在JSP中可以直接使用的对象,不需要声明,直接使用固定的名字使用即可;
- request/response
- JSP翻译生成的Java文件中,提供服务的方法是_jspService,JSP中的内容都将被翻译到该方法中;
- 分别是HttpServletRequest和HttpServletResponse类型,可以在JSP中直接使用这两个接口中的方法;
- Request代表的是四大作用域中的请求
- out/page
- 在JSP的_jspService方法中,有out,page对象;
- out的类型是JspWriter,page即当前类对象this;
- out可以用来输出内容到客户端,但是程序员一般不会使用,因为直接使用<%=%>即可以实现输出;
- pageContext/session/application
- pageContext的类型是PageContext 代表四大作用域中的页面作用域
- 有setAttribute/getAttribute/removeAttribute方法
- session的类型是HttpSession 代表四大作用中的会话
- application的类型是servletContext 代表四大作用域中的上下文
- pageContext对象封装了所有其他的内置对象
- session默认存在
- exception
- 内置对象exception比较特殊,默认情况下不存在;只有当JSP中使用指令指定该页面作为错误页面使用时才会翻译生成该内置对象;
- <%@page isErrorPage=“true” %>
- exception的类型是Throwable
- config
- 是ServletConfig类型的对象
- 在JSP中可以直接使用config对象调用ServletConfig接口中任意方法
跳转的两种方式
- 请求转发
- request.getRequestDispatcher(“b.jsp”).forward(request,response)
- 一次请求,能得到原始的请求参数
- url不会改变
不可以转发给外部地址
响应重定向
- response.sendRedirect(“b.jsp”)
- 两次请求,不能得到原始的请求参数
- url会改变
- 可以转发给外部地址
请求属性的使用
- void setAttribute(String name, Object o)
- 将任意类型对象设置为请求的属性,指定一个名字;
- Object getAttribute(String name)
- 通过属性的名字,获取属性的值;
- void removeAttribute(String name)
- 通过属性的名字,删除属性;
请求参数与请求属性
- 请求参数是用户提交请求时,自动封装到请求对象中的一些输入信息,都是String类型;
- 请求属性可以是任意类型的对象,可以用setAttribute方法将对象作为属性存储到请求对象中;
指令与动作
JSP可以通过指令元素而影响容器翻译生成Java类的整体结构;
JSP中常用的指令有三个:page、include、taglib;
page指令属性
import属性:用来引用JSP文件需要使用的类
eg: <%@ page import=”java.util.List”%>
上述代码可以在JSP文件中使用,引入JSP需要使用的Java类;
可以使用【逗号】同时引入多个包,在一个JSP文件中多次使用import;
import是page指令中唯一一个可以在一个JSP文件中多次出现的属性,其他属性在一个JSP文件中只能出现一次;
pageEncoding属性:用来设置JSP文件的页面编码格式;
- eg: <%@page pageEncoding=“utf-8”%>
session属性:用来设置JSP页面是否生成session对象;
- 该属性默认值为true,可以设置成false。
- eg: <%@page session=”false”%>
- session属性值设置为false后,该JSP翻译生成的类中将没有内置对象session,该JSP不参与会话;
errorPage属性:设置JSP页面的错误页面。当JSP中发生异常或错误却没有被处理时,容器将请求转发到错误页面;
<%@page errorPage="error.jsp"%> This is my JSP page. <br> <%=100/0%><br>
- 访问该页面将发生数学异常,而且并没有对异常进行处理,那么将跳转到错误页面error.jsp
isErrorPage属性:
- 默认值是false,可以设置为true。在JSP的错误页面中,将isErrorPage设置为true,则该页面翻译生成的Java类中,将生成exception内置对象。在error.jsp中加入代码;
- eg: <%@page isErrorPage=”true”%>
- 上述代码将error.jsp页面设置为错误页面,所以,在error.jsp翻译生成的Java类中的_jspService方法中将生成exception内置对象;
- 即使一个页面没有设置isErrorPage=“true”,也可以作为错误页面使用,区别在是否有内置对象exception内置对象产生
include指令
用来【静态包含】其他页面
- 所谓静态包含,指的是在翻译期间,把包含的页面也翻译到当前页面的Java文件中,也就是Java源文件即实现“二合一”;
- include指令的属性是【file】,实现【静态】包含,发生在【翻译】阶段
- 在main.jsp中编写如下代码: <%@ include file=”coppyright.jsp” %>
过程:翻译main.jsp时,会把copyright.jsp文件翻译后插入到main.jsp翻译生成的.java文件中的相应位置;
include动作
在JSP页面中,进行【动态包含】
- \
\是动态包含,即在运行期访问被包含的页面,并将响应结果同包含页面的响应结果合并,生成最终响应。类似在Servlet中调用RequestDispatcher的include方法进行包含;
动态include与静态include的差异
include标准动作与include指令都是实现包含其他页面的功能;
- include标准动作的属性是page,实现动态包含,发生在请求阶段;
- include指令的属性是file,实现静态包含,发生在翻译阶段;
会话跟踪
对于Web应用来说,会话(Session)就是浏览器与服务器之间的一次连续的通讯过程
常用的会话跟踪技术有四种
- URL方式:需要保存的信息直接追加到URL后
- 如:http://127.0.0.1:8080/chapter03/xxxservlet?pageNo=12
- 隐藏域方式:可以使用表单中的隐藏域保存相关信息
- \
- Cookie方式
- 将状态信息保存到【客户端】,服务器能够获得相关信息进行分析,从而生成对客户端的响应;例如简化登录功能就可以使用Cookie实现
- Session方式
- 将状态信息保存到【服务器】的会话对象中,通过唯一标记的ID值与客户端进行绑定使用;例如访问控制功能就可以使用Session实现
Cookie
- Cookie是一段保存在【客户端】的小文本
- Cookie常用API
- Cookie(String name,Object value)
- 创建Cookie对象,指定名字和对应的值
- setMaxAge(int)
- 不设置maxAge,Cookie会在会话失效时消失
- maxAge设为0
- void setValue(String newValue)
- 设置Cookie的值
- setDomain(String domain)
- 设置cookie的域名
- response.addCookie(Cookie)
- 将Cookie对象保存到相应的响应对象中
- Cookie[] cookie=request.getCookies()
- 获取请求中的所有Cookie对象,返回数组
- 设置了最大生命时间的Cookie可以在有效时间内使用,没有设置的只是临时的,浏览器关闭即失效;
Session
- Session是会话跟踪的另一种实现手段
- Session是存储在服务器上的对象,该对象由服务器创建并维护;
- 服务器为客户端与服务器的每一次会话过程都创建并维护一个Session对象;每个服务器对Session的创建和维护的底层实现有所区别;
- Tomcat使用Cookie来维护Session对象的ID值;该Cookie名字为JSESSIONID;
- 当客户端开始一次会话过程时,以Tomcat为例,简略步骤如下图:
Session属性的添加、修改、删除及Session失效的方法
session.setAttribute(String name,Object obj) 将任意类型对象设置为会话的属性,指定一个名字;
Object session.getAttribute(String name) 通过属性的名字,获取属性的值;
session.removaAttribute(String name) 通过属性的名字,删除属性;
为什么要让Session失效?
- 会话对象是存储在服务器端的对象,一直存在需要占用一定的服务器资源;
- 会话中往往保存着用户的一些数据,如果一直有效,存在一定安全隐患;
Session失效的方法
服务器都有默认的会话失效时间,Tomcat默认是30分钟
可以在web.xml中配置失效时间
<session-config> <session-timeout>50</session-timeout> </session-config>
session.setMaxInactiveInterval(int)//最大不活动的时间
session.invalidate()//立即失效
HttpSession对象如何获取
请求接口中定义了获得HttpSession对象的方法getSession;
上下文
上下文对象是用来存储全局范围信息的对象;换句话说,一个Web应用只有唯一 一个上下文对象
当服务器启动的时候,就会为每一个应用创建一个上下文对象
当服务器关闭的时候,上下文对象就销毁
上下文对象是服务器创建的,一个应用只有一个上下文对象
Servlet规范中定义了ServletContext接口,表示上下文对象
在web.xml中可以配置上下文参数,使用ServletContext中的getInitParameter方法可以获取该参数
<context-param> <param-name>version</param-name> <param-value>2.0</param-value> </context-param>
//返回ServletContext对象 ServletContext ctxt=this.getServletContext(); //获取上下文参数 String version=ctxt.getInitParameter("version"); System.out.println("上下文参数version的值:"+version);
四大作用域范围
- 页面范围:一个Servlet或JSP文件
- 请求范围:一次请求中可以访问多个Servlet或JSP; 访问的Servlet或JSP能够包含其他资源
- 会话范围:一次会话中可以包含多个请求
- 上下文范围:上下文包含所有会话
请求、会话、上下文接口都定义了与属性有关的方法,用来保存、获取、删除共享数据;
监听器与过滤器
监听器
事件发生的时间往往是不确定的,当事件发生的时候需要进行一些处理时,就可以使用监听器;
监听器相关的API包括事件类以及监听器接口
事件类定义了事件类型,监听器接口定义了监听事件的方法
Servlet API中定义了6种事件类型
上下文相关的事件
- ServletContextEvent:该类表示上下文事件,当应用上下文对象发生改变,如创建或销毁上下文对象时,将触发上下文事件;
- ServletContextAttributeEvent:该类表示上下文属性事件,当应用上下文的属性改变,如增加、删除、覆盖上下文中的属性时,将触发上下文属性事件;
- 请求相关的事件
- ServletRequestEvent:该类表示请求事件,当请求对象发生改变,如创建或销毁请求对象时,触发请求事件;
- ServletRequestAttributeEvent:该类表示请求属性事件,当请求中的属性改变,如增加、删除、覆盖请求中的属性时,触发请求属性事件;
会话相关的事件
- HttpSessionEvent:该类表示会话事件,当会话对象发生改变,如创建或销毁会话对象,活化或钝化会话对象时,将触发会话事件;
- HttpSessionBindingEvent:该类表示会话绑定事件,当会话中的属性发生变化时,如增加、删除、覆盖会话中的属性时,将触发会话绑定事件;
Servlet API中定义了8种监听器接口,用来监听不同的事件类型
请求相关的监听器
- ServletRequestListener:请求监听器,监听ServletRequestEvent事件;
- ServletRequestAttributeListener:请求属性监听器,用来监听ServletRequestAttributeEvent事件;
会话相关的监听器
- HttpSessionListener:会话监听器,监听HttpSessionEvent;
- HttpSessionActivationListener:会话活化监听器,监听HttpSessionEvent事件;
- HttpSessionAttributeListener:会话属性监听器,监听HttpSessionAttributeEvent事件;
- HttpSessionBindingListener:会话绑定监听器,监听HttpSessionAttributeEvent事件;
编写监听器的步骤是什么
写一个类实现相应的XXXLisntener接口;
重写接口中的方法,实现监听的功能;
要想监听器生效,需要在web.xml中进行配置
<listener> <listener-class>xxx.xxListener</listener-class> </listener>
过滤器
- 把通用的、相同的处理代码用过滤器实现,然后在web.xml中将过滤器配置给相关的资源使用即可
- 过滤器的开发
- 自定义类实现Filter接口
- 实现接口中的方法,重点是doFilter方法
- Filter接口中有三个方法
- void init(FilterConfig filterConfig)
- 容器初始化过滤器对象后调用该方法,其中参数可以获取过滤器配置信息;
- void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- 过滤器的服务方法,有三个参数,其中FilterChain中也定义了名字为doFilter方法,不过只有两个参数,可以把当前的请求和响应沿着过滤链进行传递;
- void destroy()
- 容器销毁过滤器对象前进行调用;
- 除了Filter接口外,与过滤器有关的还有FilterConfig和FilterChain接口
- 其中FilterConfig接口中定义了如下方法
- String getFilterName()
- 返回web.xml中配置的Filter的名字信息
- String getInitParameter(java.lang.String name)
- 返回web.xml中配置的Filter的初始化参数的值;与Servlet初始化参数类似,只能在当前的Filter中使用;
- Enumeration<\String> getInitParameterNames()
- 返回web.xml中配置的Filter的所有初始化参数的名字
- ServletContext getServletContext()
- 返回当前的上下文对象
- doFilter(ServletRequest request, ServletResponse response)
- 如果当前的过滤器之后还有其他过滤器,则调用下一个过滤器;如果已经是最后一个过滤器,则调用目标资源;同时将请求和响应传到下一个资源;此方法是过滤器编程中最常用的方法;
编写编码格式过滤器CharacterFilter @WebFilter("*") public class CharacterFilter implements Filter { private static final String UTF="utf-8"; @Override public void destroy() { } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { arg0.setCharacterEncoding(UTF); arg2.doFilter(arg0, arg1); } @Override public void init(FilterConfig arg0) throws ServletException { } }
编写过滤器后,要使过滤器生效,必须在web.xml中进行配置,主要配置信息有:
过滤器的名字和过滤器的类信息
- 过滤器对哪些URL生效
- 过滤器对这些URL生效时的访问方式
- 过滤器初始化参数
<!--过滤器配置--> <filter> <filter-name>sss</filter-name> <filter-class>ssss.ssss</filter-class> </filter> <filter-mapping> <filter-name>sss</filter-name> <!--配置过滤器能够过滤的资源URL,此处是对所有资源可以过滤--> <url-pattern>*</url-pattern> <!--配置以何种方式访问url-pattern指定的资源才能被过滤: 1、REQUEST:直接URL访问、响应重定向、超级链接、表单提交、静态包含 2、FORWARD:请求转发 3、INCLUDE:动态包含【后续学习】 4、ERROR(错误页面跳转)--> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
MVC模式
- MVC(Model-View-Controller)是一种软件架构设计模式
MVC模式将软件的代码按照模型(M)、视图(V)、控制器(C)三部分组织,如下图
使用MVC模式构建应用,具有以下优势
- 耦合性低:视图层和业务层分离,耦合性降低,可以独立修改
- 重用性高:可以用不同的视图访问模型部分,实现在不同终端上访问应用
- 可维护性高:视图与业务分离,降低了维护成本
MVC模式中有三个角色,分别是M模型,V视图,C控制器
Servlet和JSP之间共享数据一般使用请求、会话、上下文范围的属性进行
- HttpServletRequest/HttpSession/ServletContext接口中都定义了存取、查询、删除属性的方法
- 使用原则:尽量用范围小的属性,即,请求范围内共享即可就用请求,以此类推;否则会造成资源浪费,降低安全性
- MVC模式中,控制器和视图之间需要进行跳转
- redirect:调用响应接口的sendRedirect方法,响应重定向,相当于重新请求新的资源,当前请求对象不会到目标资源;
- forward: 调用请求转发器接口的forward方法,请求转发,将当前的请求、响应对象转发到目标资源;
- include:调用请求转发器接口的include方法,动态包含,将目标资源的请求、响应对象包含到当前资源;
EL与JSTL
- EL
- EL是Expression Language的简称,即表达式语言
- EL在JSP中使用,服务器会对其进行解析翻译,生成相应的Java代码;
- EL的作用是用来在JSP页面输出动态内容,可以替代JSP中的表达式元素<%=%>
- EL的一般格式如下:${EL表达式}
- EL提供了11个内置对象
- 2个内置对象为了方便输出请求参数: param/paramValues;
- 4个内置对象为了方便输出各个范围的属性: pageScope/ requestScope/sessionScope /applicationScope;
- 2个与请求头有关的内置对象:header/headerValues;
- 2个其他内置对象:cookie/initParam;
- 1个特殊的内置对象pageContext;