码农的世界程序员

JavaWeb知识点笔记

2018-12-21  本文已影响5人  海若Hero

1.1 Servlet

1.1.1 什么是Servlet

  1. 获取请求数据

  2. 处理请求

  3. 完成响应

servlet 中的方法大多数不由我们调用,而是由 tomcat 调用,并且 servlet 对象也不由我们创建,由 tomcat 创建

> void init(ServletConfig) 它会在servlet对象创建之后马上执行,并只执行一次

> void service(ServletRequest,ServletResponse) 它会被调用多次 , 每次处理请求都是在调用这个方法

> void destory() 它会在servlet被销毁之前调用,只会被调用一次 [留遗言]

以上三个方法都为生命周期方法

> ServletConfig getServletConfig() 用来获取 servlet 配置信息

> String getServletInfo() 获取 servlet 信息

1.1.2 实现Servlet的方式

1.1.3 Servlet第一例

<servlet>
<servlet-name>xxx</servlet-name>
<servlet-class>cn.itcast.MyServlet</servlet-class> 将路径和类绑在一起,此处为包名
</servlet>
<servlet-mapping>
<servlet-name>xxx</servlet-name>
<url-pattern>/myservlet</url-pattern> 此处为路径
</servlet-mapping>

注意!两处的 servlet-name 要一致

当用户在地址栏中访问:http://localhost:8080/day04_1/myservlet时,会执行System.out.println("hello servlet!");

1). 服务器创建Servlet:

Servlet 第一次被请求时,或服务器启动时,服务器会创建 Servlet 实例。

服务器只为一个类型的 Servlet 创建一个实例对象,所以 Servlet 是单例的;

2). 服务器初始化Servlet:

3). 服务器使用Servlet处理请求:

因为 Servlet 是单例的,所以可能在同一时刻一个 Servlet 对象会被多个请求同时访问,所以这可能出现线程案例问题

Servlet 不是线程案例的,这有助与提高效率,但不能让 Servlet 具有状态,以免多个线程争抢数据

4). 服务器销毁Servlet

服务器通常不会销毁 Servlet ,通常只有在服务器关闭时才会销毁 Servlet

1.1.4 ServletConfig

ServletConfig是Servlet中的init()方法的参数类型,服务器会在调用init()方法时传递ServletConfig对象给init()方法。

ServletConfig 对象封装了 Servlet web.xml 中的配置信息,它对应 <servlet> 元素。

ServletConfig类的功能有:

在web.xml文件中,配置<servlet>时可以为<servlet>配置0~N个初始化参数

1.1.5 GenericServlet

GenericServlet是Servlet接口的实现类,但它是一个抽象类,它唯一的抽象方法就是 service() 方法

GenericServlet实现了Servlet方法:

GenericServlet实现了ServletConfig接口:

GenericServlet添加了init()方法:

service 方法中也可以使用 servletconfig 成员 , 只要在 init 方法之前就可以

不可贸然覆盖init方法,其中有config对象

可以覆盖init()无参函数

1.1.6 HttpServlet

HttpServlet是GenericServlet的子类,它专注HTTP请求

HttpServlet类的方法:

> 把ServletRequest强转成HttpServletRequest

> 把ServletResponse强转成HttpServletResponse

> 调用本类添加的void service(HttpServletRequest,HttpServletResponse)方法

> 调用request的getMethod()获取请求方式

> 如果请求方式为GET,那么调用本类添加的doGet(HttpServletRequest,HttpServletResponse)方法

> 如果请求方式为POST,那么调用本类添加的doPost(HttpServletRequest,HttpServletResponse)方法

如果是通过继承HttpServlet类来自定义Sevlet的话,那么:

1.1.7 web.xml

servlet创建两种方式,

1.servlet第一次收到请求创建

2.服务器在启动时就创建

1.1.8 defaultServlet

default优先级最低,如果一个请求没有处理,那么它来处理,显示404

url-pattern 匹配的是 /

当访问路径不存在时,会执行defaultServlet,其实在访问index.html时也是在执行这个servlet

1.1.9 jspServlet

访问jsp页面时,会调用jspServlet,通过将动态资源转为静态资源,然后用response进行响应

1.1.10 session-config

session过期时间

1.2 MIME 多功能网际邮件扩充协议

多用途扩展类型,包含jpeg gif等,在这里定义了类型:

xml类型

txt类型

jpg/jpeg类型

doc类型

docx

1.2.1 什么是MIME-Type

首先,我们要了解浏览器是如何处理内容的。在浏览器中显示的内容有 HTML、有 XML、有 GIF、还有 Flash ……那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME Type,也就是该资源的媒体类型。

媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type 来表示的

例如:Content-Type: text/HTML

表示内容是 text/HTML 类型,也就是超文本文件。为什么是“text/HTML”而不是“HTML/text”或者别的什么?MIME Type 不是个人指定的,是经过 ietf 组织协商,以 RFC 的形式作为建议的标准发布在网上的,大多数的 Web 服务器和用户代理都会支持这个规范 (顺便说一句,Email 附件的类型也是通过 MIME Type 指定的)。

通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的格式,一般只能以 application/x- 开头。

XHTML 正是一个获得广泛应用的格式,

因此,在 RFC 3236 中,说明了 XHTML 格式文件的 MIME Type 应该是application/xHTML+XML。

当然,处理本地的文件,在没有人告诉浏览器某个文件的 MIME Type 的情况下,浏览器也会做一些默认的处理,这可能和你在操作系统中给文件配置的 MIME Type 有关。

比如在 Windows 下,打开注册表的“HKEY_LOCAL_MACHINESOFTWAREClassesMIMEDatabaseContent Type”主键,你可以看到所有 MIME Type 的配置信息。

1.2.2 <url-pattern>

<url-pattern>是<servlet-mapping>的子元素,用来绑定Servlet的访问路径

可以在一个<servlet-mapping>中给出多个<url-pattern>,也就是说一个Servlet可以有多个访问路径:

<servlet-mapping>

<servlet-name>xxx</servlet-name>

<url-pattern>/helo1<url-pattern>

<url-pattern>/hello2<url-pattern>

</servlet-mapping>

还可以在<url-pattern>中使用通配符,即“*”。

注意:

1.2.3 welcome-file-list

设置欢迎界面

1.3 ServletContext

ServletContext是Servlet三大域对象之一

ServletContext在服务器启动时创建,在服务器关闭时销毁,一个JavaWeb应用只创建一个ServletContext对象

一个项目只有一个ServletContext对象

1.3.1 ServletContext概述

服务器会为每个应用创建一个ServletContext对象:

ServletContext对象的创建是在服务器启动时完成的;

ServletContext对象的销毁是在服务器关闭时完成的。

ServletContext对象的作用是在整个Web应用的动态资源之间共享数据!例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了。

不能用AServlet调用BServlet方法,会使耦合过紧

1.3.2 ServletContext的功能分类:

1.3.3 获取ServletContext对象

在HttpServlet中可以通过以下方法来获取ServletContext对象

在void init(ServletConfig config)中:

ServletContext context = config.getServletContext();

ServletConfig类的getServletContext()方法可以用来获取ServletContext对象;

在GenericeServlet或HttpServlet中获取ServletContext对象:

GenericServlet类有getServletContext()方法,所以可以直接使用this.getServletContext()来获取;

1.3.4 存取数据

因为在一个JavaWeb应用中,只有一个ServletContext对象,所以在ServletContext中保存的数据可以共整个JavaWeb应用中的动态资源共享

ServletContext是Servlet三大域对象之一,域对象内部有一个Map,用来保存数据

域对象的功能****(****用来在多个****servlet****中传递数据****)

ServletContext是JavaWeb四大域对象之一:

PageContext;

ServletRequest;

HttpSession;

ServletContext;

1. 存数据

> servletContext.setAttribute("xxx", "XXX"),添加域数据

> servletContext.setAttribute("xxx", "XXXX"),覆盖域数据,因为在域中已经存在了名为xxx的数据,所以这次就是覆盖了

2. 取数据

1.3.5 读取web.xml中配置的应用初始化参数

Servlet也可以获取初始化参数,但它是局部的参数;也就是说,一个Servlet只能获取自己的初始化参数,不能获取别人的,即初始化参数只为一个Servlet准备!

可以配置公共的初始化参数,为所有Servlet而用!这需要使用ServletContext才能使用!

<context-param>

<param-name>p1</param-name>

<param-value>v1</param-value>

</context-param>

<context-param>

<param-name>p2</param-name>

<param-value>v2</param-value>

</context-param>

1.3.6 获取项目资源

需要动态获取地址,引入

String path = servletContext.getRealPath("/WEB-INF/a.jpg");

返回值为/WEB-INF/a.jpg真实路径,即磁盘路径:C:/tomcat6/wabapps/hello/WEB-INF/a.jpg

如:

InputStream in = servletContext.getResourceAsStream("/WEB-INF/a.jpg");

返回的是a.jpg的输入流对象,可以从流中得到a.jpg的数据

Set<String> paths = servletContext.getResourcePaths("/WEB-INF");

返回的Set中包含如下字符串:

> /WEB-INF/lib/

> /WEB-INF/classes/

> /WEB-INF/web.xml

> /WEB-INF/a.jpg

1.3.7 获取类路径资源

可以通过Class类的对象来获取类路径下的资源,对应JavaWeb应用的类路径就是classes目录下的资源

例如:

InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("a.jpg");

获取的是:/WEB-INF/classes/cn/itcast/servlet/a.jpg,即与MyServlet.class同目录下的资源

例如:

InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("/a.jpg");

获取的是:/WEB-INF/classes/a.jpg,即类路径的根目录下的资源,类路径的根目录就是/classes目录

IOUtils 输入出流工具类,可以转换为字符串


练习:统计网站访问量

一个项目中所有的资源被访问都要对访问量进行累加!

创建一个int类型的变量,用来保存访问量,然后把它保存到ServletContext的域中,这样可以保存所有的Servlet都可以访问到!

最初时,ServletContext中没有保存访问量相关的属性;

当本站第一次被访问时,创建一个变量,设置其值为1;保存到ServletContext中;

当以后的访问时,就可以从ServletContext中获取这个变量,然后在其基础之上加1。

获取ServletContext对象,查看是否存在名为count的属性,如果存在,说明不是第一次访问,如果不存在,说明是第一次访问;

第一次访问:调用Servletcontext的setAttribute()传递一个属性,名为count,值为1;

第2~N次访问:调用ServletContext的getAttribute()方法获取原来的访问量,给访问量加1,再调用Servletcontext的setAttribute()方法完成设置。

1.3.8 参数(parameter)和属性(Attribute)的区别

区别:

参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中

提供的,若是POST方法是从请求体(request body)中提供的;

属性(attribute)是服务器端的组件(JSP或者Servlet)利用requst.setAttribute()设置的

参数(parameter)的值只能读取不能修改,读取可以使用request.getParameter()读取;

属性(attribute)的值既可以读取亦可以修改,读取可以使用request.setAttribute(),设置可使用request.getAttribute()

参数(parameter)不管前台传来的值语义是什么,在服务器获取时都以String类型看待,并且客户端的参数值只能是简单类型的值,不能是复杂类型,比如一个对象。

属性(attribute)的值可以是任意一个Object类型。

共同点

二者的值都被封装在request对象中。


1.4 Cookie

1.4.1 Http协议与Cookie(了解)

 response.addHeader("Set-Cookie", "aaa=AAA");
 response.addHeader("Set-Cookie", "bbb=BBB");

> 1 Cookie 最大 4KB

> 1 个服务器最多向 1 个浏览器保存 20 Cookie

> 1 个浏览器最多可以保存 300 Cookie

1.4.2 Cookie的用途

********** Cookie 是不能跨浏览器的! ***********

1.4.3 JavaWeb中使用Cookie

> 使用request获取Cookie请求头

> 使用repsonse.addCookie()方法向浏览器保存Cookie

> 使用request.getCookies()方法获取浏览器归还的Cookie(* 判断 null) *

Cookie第一例:

> 一个jsp保存cookie, a.jsp

> 另一个jsp获取浏览器归还的cookie! b.jsp

1.4.4 Cookie详解

> maxAge>0:浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值决定。

> maxAge<0:Cookie只在浏览器内存中存在,当用户关闭浏览器时,浏览器进程结束,同时Cookie也就死亡了。

> maxAge=0:浏览器会马上删除这个Cookie!

> Cookie的path并不是设置这个Cookie在客户端的保存路径!!!

> Cookie的path由服务器创建Cookie时设置

> 当浏览器访问服务器某个路径时,需要归还哪些Cookie给服务器呢?这由Cookie的path决定。

> 浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会归还这个Cookie。

例如:

<> aCookie.path=/day11_1/; bCookie.path=/day11_1/jsps/; cCookie.path=/day11_1/jsps/cookie/;

<> 访问:/day11_1/index.jsp时,归还:aCookie

<> 访问:/day11_1/jsps/a.jsp时,归还:aCookie、bCookie

<> 访问:/day11_1/jsps/cookie/b.jsp时,归还:aCookie、bCookie、cCookie

Cookie的path默认值:当前访问路径的父路径。例如在访问/day11_1/jsps/a.jsp时,响应的cookie,那么这个cookie的默认path为/day11_1/jsps/

> domain用来指定Cookie的域名!当多个二级域中共享Cookie时才有用。

> 例如;www.baidu.comzhidao.baidu.comnews.baidu.comtieba.baidu.com之间共享Cookie时可以使用domain

> 设置domain为:cookie.setDomain(".baidu.com");

> 设置path为:cookie.setPath("/");

Cookie中不能存在中文!!!

// 保存

Cookie c = new Cookie("username", URLEncoder.encode("张三", "utf-8"));//出错!

response.addCookie(c);

// 获取

Cookie[] cs = request.getCookies();

if(cs != null) {

for(Cookie c : cs){

if("username".equals(c.getName())) {

String username = c.getValue();

username = URLDecoder.decode(username, "utf-8");

}

}

}

============================================

1.5 HttpSession

1.5.1 HttpSession概述

1.5.2 HttpSession的作用

会话:一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器!

Servlet中得到session对象:HttpSession session = request.getSession();

Jsp中得到session对象:session是jsp内置对象之下,不用创建就可以直接使用!

> void setAttribute(String name, Object value);

> Object getAttribute(String name);

> void removeAttribute(String name);

1.5.3 HttpSession原理(理解)

> 获取Cookie中的JSESSIONID:

<> 如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中

<> 如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中

<> 如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了。

<> 返回session

如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在。

下次请求时,再次执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是同一session对象。

第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象。

1.5.4 HttpSession其他方法:

1.5.5 web.xml中配置session的最大不活动时间

<session-config>

<session-timeout>30</session-timeout>

</session-config>

1.5.6 案例1:演示session中会话的多次请求中共享数据

> 第一个请求:访问AServlet

> 第二个请求:访问BServlet

1.5.7 案例2:演示保存用户登录信息(精通)

> login.jsp:登录页面

> succ1.jsp:只有登录成功才能访问的页面

> succ2.jsp:只有登录成功才能访问的页面

> LoginServlet:校验用户是否登录成功!

> login.jsp:提供登录表单,提交表单请求LoginServlet

> LoginServlet:获取请求参数,校验用户是否登录成功

<> 失败:保存错误信息到request域,转发到login.jsp(login.jsp显示request域中的错误信息)

<> 成功:保存用户信息到session域中,重定向到succ1.jsp页面,显示session域中的用户信息

> succ1.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息

> succ2.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息

只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就一起存在!那么用户访问succ1和succ2就会通过!

1.6 JSP

1.6.1 JSP三大指令

一个jsp页面中,可以有0~N个指令的定义!

  1. page --> 最复杂:%@page language="java" info="xxx"...%

> pageEncoding:它指定当前jsp页面的编码,只要不说谎,就不会有乱码!在服务器要把jsp编译成.java时需要使用pageEncoding!

> contentType:它表示添加一个响应头:Content-Type!等同与response.setContentType("text/html;charset=utf-8");

> 如果两个属性只提供一个,那么另一个的默认值为设置那一个。

> 如果两个属性都没有设置,那么默认为iso

> errorPage:当前页面如果抛出异常,那么要转发到哪一个页面,由errorPage来指定

> isErrorPage:它指定当前页面是否为处理错误的页面!当该属性为true时,这个页面会设置状态码为500!而且这个页面可以使用9大内置对象中的exception!

 <error-page>

<error-code>404</error-code>

<location>/error/errorPage.jsp</location>

</error-page>

<error-page>

<error-code>500</error-code>

<location>/error/errorPage.jsp</location>

</error-page>

<error-page>

<exception-type>java.lang.RuntimeException</exception-type>

<location>/index.jsp</location>

</error-page>

autoFlush:指定jsp的输出流缓冲区满时,是否自动刷新!默认为true,如果为false,那么在缓冲区满时抛出异常!

buffer:指定缓冲区大小,默认为8kb,通常不需要修改!

language:指定当前jsp编译后的语言类型,默认值为java。

info:信息!

isThreadSafe:当前的jsp是否支持并发访问!

session:当前页面是否支持session,如果为false,那么当前页面就没有session这个内置对象!

extends:让jsp生成的servlet去继承该属性指定的类!

  1. include --> 静态包含
  1. taglib --> 导入标签库

prefix:指定标签库在本页面中的前缀!由我们自己来起名称!

uri: 指定标签库的位置!

 <%@taglib prefix="s" uri="/struts-tags"%> 前缀的用法<s:text>

=========================================

1.6.2 JSP九大内置对象

  1. pageContext

ServletContext:整个应用程序

session:整个会话(一个会话中只有一个用户)

request:一个请求链!

pageContext:一个jsp页面!这个域是在当前jsp页面和当前jsp页面中使用的标签之间共享数据!

域对象

代理其他域:pageContext.setAttribute("xxx", "XXX", PageContext.SESSION_SCOPE);

全域查找:pageContext.findAttribute("xxx");从小到大,依赖查找!

获取其他8个内置对象:

=========================================

1.6.3 JSP动作标签

这些jsp的动作标签,与html提供的标签有本质的区别。

* 动作标签是由tomcat(服务器)来解释执行!它与java代码一样,都是在服务器端执行的!

* html由浏览器来执行!

%@include和<jsp:include>有什么不同!

=========================================

1.7 JavaBean

1.7.1 JavaBean的规范:

  1. 必须要有一个默认构造器

  2. 提供get/set方法,如果只有get方法,那么这个属性是只读属性!

  3. 属性:有get/set方法的成员,还可以没有成员,只有get/set方法。属性名称由get/set方法来决定!而不是成员名称!

  4. 方法名称满足一定的规范,那么它就是属性!boolean类型的属性,它的读方法可以是is开头,也可以是get开头!

1.7.2 内省:

内省类 --> Bean信息 --> 属性描述符 --> 属性的get/set对应的Method! --- > 可以反射了!


commons-beanutils,它是依赖内省完成!

commons-beanutils.jar

commons-logging.jar

BeanUtils.getProperty(Object bean, String propertyName)

BeanUtils.setProperty(Object bean, String propertyName, String propertyValue)

BeanUtils.populate(Map map, Object bean)

CommontUtils.toBean(Map map, Class class)

注意导包的时候后面写.*


1.7.3 javaBean导航

<%

Address address = new Address();

address.setCity("北京");

address.setStreet("西三旗");

Employee emp = new Employee();

emp.setName("李小四");

emp.setSalary(123456);

emp.setAddress(address);

request.setAttribute("emp", emp);

%>

1.7.4 jsp中与javaBean相关的标签

=========================================

1.8 EL表达式

1.8.1 EL基本概念

EL是JSP内置的表达式语言!

1.8.2 EL表达式读取四大域

* ${pageScope.xxx}、${requestScope.xxx}、${sessionScope.xxx}、${applicationScope.xxx},指定域获取属性!

<h3>使用el获取request域的emp</h3>

${requestScope.emp.address.street }<!-- request.getAttribute("emp").getAddress().getStreet() --><br/>

1.8.3 EL表达式与内置对象

EL可以输出的东西都在11个内置对象中!11个内置对象,其中10个是Map!pageContext不是map,它就是PageContext类型,1个项9个。

<context-param>

<param-name>xxx</param-name>

<param-value>XXX</param-value>

</context-param>

<context-param>

<param-name>yyy</param-name>

<param-value>YYY</param-value>

</context-param>

${initParam.xxx}

=========================================

1.8.4 EL函数库(由JSTL提供的)

<%@ tablib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

String toUpperCase(String input):把参数转换成大写

String toLowerCase(String input):把参数转换成小写

int indexOf(String input, String substring):从大串,输出小串的位置!

boolean contains(String input, String substring):查看大串中是否包含小串

boolean containsIgnoreCase(String input, String substring):忽略大小写的,是否包含

boolean startsWith(String input, String substring):是否以小串为前缀

boolean endsWith(String input, String substring):是否以小串为后缀

String substring(String input, int beginIndex, int endIndex):截取子串

String substringAfter(String input, String substring):获取大串中,小串所在位置后面的字符串

substringBefore(String input, String substring):获取大串中,小串所在位置前面的字符串

String escapeXml(String input):把input中“<”、">"、"&"、"'"、""",进行转义

String trim(String input):去除前后空格

String replace(String input, String substringBefore, String substringAfter):替换

String[] split(String input, String delimiters):分割字符串,得到字符串数组

int length(Object obj):可以获取字符串、数组、各种集合的长度!

String join(String array[], String separator):联合字符串数组!

=========================================

1.8.5 EL自定义函数库

<function>

<name>fun</name>

<function-class>cn.itcast.fn.MyFunction</function-class>

<function-signature>java.lang.String fun()</function-signature>

</function>
<%@ taglib prefix="it" uri="/WEB-INF/tlds/itcast.tld" %>
${it:fun() }
tobehero666.png
上一篇 下一篇

猜你喜欢

热点阅读