JavaWeb总结

JavaWeb总结

文章目录

JavaWeb的概念

JavaWeb是指使用java语言配合web容器编写出可以通过浏览器访问的程序的总称,它是基于请求和响应来进行开发的。
请求(request)就是客户端向服务端发送数据,
响应(response)就是服务器给客户端回传数据
所以我们要编写web程序通常就需要配置好各项环境和各种包,其中服务器就是必不可少的一项。

常用的Web服务器

在这里插入图片描述

一、Tomcat

1、什么是Tomcat?

tomcat是一个开源而且免费的jsp服务器,属于轻量级应用服务器。它可以实现JavaWeb程序的装载。

2、Tomcat的下载和在IDEA中的安装配置

示范环境为:win10 64位系统,IDEA,Tomcat9

第一步:下载Tomcat服务器

首先到Tomcat的官网(http://tomcat.apache.org/)下载Tomcat,(根据自己的jdk版本选择tomcat版本,如果版本不相应的话可能会导致运行报错,比如我是jdk14,可以下载Tomcat8),下载完后将解压包移动到随意一个路径,最好不要含有中文名,例如我解压在D:\tomcat 中
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

第二步:配置Tomcat环境变量

不配置环境变量也可以,可以直接从Tomcat安装路径bin目录中找到"startup.bat"打开服务器
1、右击此电脑->属性->高级系统设置->高级->环境变量
在这里插入图片描述2、在"系统变量"里新建变量名:CATALINA_HOME,变量值是第一步下载的Tomcat安装包解压好的路径。
如果要配置多个版本的Tomcat的话需要在配置一个CATALINA_BASE变量,详情自己百度“如何配置多个版本的Tomcat”
在这里插入图片描述3、在"系统变量"里打开Path变量,添加变量值:

%CATALINA_HOME%\bin

在这里插入图片描述

第三步:启动Tomcat服务器

打开命令提示窗口输入catalina就可以看到Tomcat的详细信息,
在这里插入图片描述输入"catalina run"或者"startup"打开tomcat服务器
在这里插入图片描述
不要关闭这个命令行窗口,打开浏览器,在地址栏中输入http://localhost:8080,如果出现小猫页面则代表安装成功

在这里插入图片描述

控制台乱码现象解决方法

找到tomcat安装目录,找到conf下的logging.properties文件,将其中的
java.util.logging.ConsoleHandler.encoding = UTF-8
修改为
java.util.logging.ConsoleHandler.encoding = GBK
即可解决

Tomcat文件目录介绍

在这里插入图片描述

第四步:将Tomcat服务器整合到IDEA中使用

打开IDEA->File->Settings->Build,Execution,Deployment->Application Servers 配置好tomcat的路径,完成
在这里插入图片描述在这里插入图片描述

第五步:创建一个动态Web工程项目

1、File->New->Project->Java Enterprise–>Web Application->Next->Finish,这样一个动态Web工程项目就创建好了
在这里插入图片描述

二、Servlet

1、什么是Servlet?

Servlet是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。它可以接受客户端发送的请求并响应给客户端。

2、如何创建一个Servlet?

第一步:创建Servlet实现类或者继承类

Servlet是一个java程序,所以我们在src下面创建一个包去放Servlet程序,可以用new->Servlet(注意是否使用注解创建serlvet)或者新建一个类去实现Servlet接口或者继承HttpServlet类(一般实际开发中都是选择后者)

/* 继承HttpServlet类 */
public class servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}
/* 实现Servlet接口 */
public class servlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

第二步:在web.xml文件中配置servlet的信息

web.xml文件在WEB-INF中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- servlet标签是给Tomcat配置Servlet程序 -->
    <servlet>
        <!--  servlet-name标签是给servlet程序起一个别名(一般是类名) -->
        <servlet-name>servlet</servlet-name>
        <!--  servlet-class是servlet程序的全类名 -->
        <servlet-class>com.linzhijie.Servlet.servlet</servlet-class>
    </servlet>
    <!-- servlet-mapping标签是给servlet程序配置访问地址  -->
    <servlet-mapping>
        <!--  servlet-name标签的作用是告诉服务器当前配置的地址是给哪个servlet使用 -->
        <servlet-name>servlet</servlet-name>
        <!-- url-pattern标签是配置访问地址,就是要访问到这个servlet要前往的地址 -->
        <url-pattern>/servlet</url-pattern>
    </servlet-mapping>
</web-app>

2.1 为什么选择继承HttpServlet类而不是实现Servlet接口?

因为Servlet是一个接口,所以实现servlet接口必须实现接口中所有的方法,而继承HttpServlet类可以只重写类中的一个或多个方法

3、Servlet的生命周期

在第一次访问的时候首先会执行Servlet构造器方法,然后执行init方法,随后每次访问都会调用service方法,在工程停止时会执行destroy方法。doGet方法和doPost方法在具体需要的时候执行。

4、ServeletConfig类

ServletConfig是Servlet程序的配置信息类,每个Servlet程序创建时就会自动创建一个ServletConfig对象,它可以获取Servlet程序的别名,获取初始化参数init-param(如果有在web.xml的servlet标签里配置init-param的话),获取ServletContext(上下文对象)对象

5、ServletContext类

Servelt上下文对象,ServletContext是一个域对象,一个Web工程只有一个ServletContext对象实例,它在Web工程部署启动的时候创建,在Web工程停止的时候销毁。

5.1 什么是域对象?

像Map一样存取数据的对象,这里的域指是整个Web工程目录,与Map的区别:
在这里插入图片描述

5.2 ServletContext的用处

  1. 获取在web.xml配置的上下文参数(在web-app标签中即可,不受其他标签约束)
  2. 获取当前的工程路径
  3. 获取工程部署后在服务器硬盘的绝对路径
  4. 像Map一样存取数据
    在这里插入图片描述

6、HttpServletRequest类

我们通过HttpServletRequest对象从服务器获取客户端(浏览器)的信息

6.1 常用方法

在这里插入图片描述

6.2 请求转发(包含)

请求转发(包含)指的是服务器收到客户端的请求后从一个资源跳转到另外一个资源的操作。
举个例子来说客户端发起了一次请求,第一个servlet程序要你稍等一下,然后它自己到另一个servlet去获取你想要的资源给你,最后你拿着资源回到客户端(浏览器)。

6.2.1 特点
  1. 浏览器的地址栏没有发生变化
  2. 一次请求一次响应
  3. 共享Request域中的数据
  4. 只能访问该网站的内部资源和WEB-INF中的资源(如servlet,jsp,html等)
  5. 不可以访问网站外部的资源(如转发到百度页面)
6.2.2 使用

使用Request对象实现请求转发(包含),需要用到下面两个方法
在这里插入图片描述什么时候使用请求转发什么时候使用请求包含看这篇博文
请求转发和请求包含

request.getRequestDispatcher("/要转发的资源路径").forward(request,response);

7、HttpServletResponse类

我们通过HttpServletResponse对象从服务器返回给客户端(浏览器)信息

7.1 常用的两个输出流

在这里插入图片描述

7.2 请求重定向

请求重定向指客户端给服务器发请求,然后服务器回传一个地址让客户端去新地址访问。像一个网址已经迁移到别的地址,然后你仍然去访问这个地址,它就会回传一个新地址让你去重新访问。

7.2.1 特点
  1. 浏览器地址栏会改变
  2. 请求-响应-再请求
  3. 不共享Request域中的数据
  4. 不能访问WEB-INF中的资源
  5. 可以访问工程之外的资源(比如百度等网站)
7.2.2 使用

在这里插入图片描述

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.sendRedirect("http://www.baidu.com");
}

8、请求和响应的中文乱码解决

设置请求体的字符即为UTF-8就可以解决请求的中文乱码问题,最好在进行其他操作之前设置。

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setCharacterEncoding("UTF-8");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html; charset=utf-8");
}

三、JSP

1、什么是JSP?

JSP(全称Java Server Pages),是一种动态网页开发技术,它的本质是一种Servlet,它的出现大部分是因为用常规servlet回传html页面数据太过于繁琐,开发起来成本较高。

2、JSP的本质

JSP的本质是一个Servlet程序,当我们第一次访问jsp页面时, 服务器会把jsp页面翻译成一个java源文件,并把它编译成字节码文件进行运行,其中查看你源文件的内容会发现源文件的类归根结底是间接继承HttpServlet,并且通过out.println()将页面的内容输出。

3、JSP页面的使用

JSP页面除了静态的html代码外还有许多语法让我们去使用,其中包括头部的page指令、声明脚本、表达式脚本、代码脚本等脚本供我们使用开发。

3.1 头部page指令

通常jsp页面的第一行代码都是以下这行代码,这是jsp页面中的page指令,它控制着jsp页面中的一些重要的属性和行为,不只只有这两个属性。一个jsp页面可以含有多个头部指令。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

以上两个属性及其他属性介绍,
在这里插入图片描述

3.2 JSP其他指令

在这里插入图片描述

3.2.1 引入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

prefix是定义的标签的前缀,uri是要使用的标签库的一个资源的定位

3.2.2 静态包含

静态包含就是将被包含的文件编译好后复制到包含的页面中输出,像是将一个页面分多个板块,然后都分离开来处理最后再用静态包含拼接起来成一个页面。

<%@include file="1.jsp"%>

3.3 脚本程序

脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的。

<% 代码片段 %>
3.3.1 声明脚本

一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。

<%! int i = 0; %> 
<%! int a, b, c; %> 
<%! Circle a = new Circle(2.0); %> 
3.3.2 表达式脚本

表达式脚本可以在jsp页面代码中的任意一个位置输出数据,但是不能以分号来结束表达式。

<%!double balance=100.0; %>
<h1>您的余额为<%=balance%></h1>
3.3.3 注释

在这里插入图片描述

4、JSP九大内置对象

九大内置对象就是JSP的隐置对象,它们是JSP页面中的java对象
在这里插入图片描述

request对象

request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。

response对象

通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。

out对象

jsp页面的输出流对象。

out对象的输出和response.getWriter()的输出的区别

两者的输出虽然都是向页面输出信息的,但是他们的输出顺序和执行顺序是不同的。
out对象有一个out缓冲区,我们使用out对象输出的时候它会把输出的数据写入out缓冲区,out.flush()刷新操作会将out缓冲区的数据追加到response缓冲区中,最后才输出。
而response.getWriter()的输出则是直接写入response缓冲区,然后执行刷新操作输出到页面中。

session对象

session对象用来跟踪在各个客户端请求间的会话。

application对象

application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。 这个对象在JSP页面的整个生命周期中都代表着每个JSP页面。这个对象在每个JSP页面初始化时被创建,随着jspDestroy()方法的调用即关闭服务器而被移除。
通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。

config对象

config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。
这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。

pageContext 对象

代表整个JSP页面,application是pageContext的一种。 这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。
pageContext对象也包含了传给JSP页面的指令信息,包括缓存信息,ErrorPage URL,页面scope等。看起来pageContext对象的作用域范围很大,但其实只是在一个jsp页面中的作用域。

page 对象

这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。
page 对象就是this对象的同义词。

exception 对象

exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。

5、JSP四大域对象

域对象是可以存取数据的对象,以下这四个域对象的功能一样,只是数据的存取范围不同。
1、pageContext域对象只在当前这个jsp页面存取数据,离开了当前的jsp页面pageContext域对象的数据就丢失了。
2、request域域对象只在相同一个request链中存取数据,如果发起其他请求的话这个request域对象中的数据也就没有了。
3、session域对象在创建session的生命周期中(默认为30分钟)和浏览器关闭之前存取数据,如果关闭了浏览器或者session过期时间到了,那么session域对象中的数据就丢失了。
4、application域对象,它的作用域范围值四个域对象中最大的,只要web工程不销毁,他就会一直可以存取数据,直到服务器关闭。
在这里插入图片描述

6、JSP的其他标签

6.1 动态包含

<jsp:include page="/footer.jsp"></jsp:include>

6.2 转发标签

<jsp:forward page="index.jsp"></jsp:forward>

四、EL表达式和JSTL标签库

EL表达式和JSTL标签库都是为了程序员在jsp中能更方便地进行jsp页面的数据以及功能的操作和维护

1、EL表达式(JSP表达式语言)

1.1 定义

EL(Expression Language)表达式,是JSP表达式语言。它提供了在 JSP 中简化表达式的方法,让JSP输出的代码更加简化。

1.2 作用

代替JSP页面中的表达式脚本进行数据的输出。
当访问的数据为null时,使用EL表达式将会输出空串,
而使用JSP表达式脚本输出的话会是一个"null"字符串。

1.3 语法格式

${表达式}

表达式可以是 数字、字符串、数组、对象等等

1.4 基础操作符

包括.,[],()运算符,算数运算符,关系运算符,逻辑运算符,empty运算,以及三元运算符

操作符描述
.访问Bean属性或者其他属性
[]访问数组或者链表中的元素
()组织一个子表达式以改变优先级
+, - ,* ,/ ,div ,% ,mod加减乘除取模
== ,eq相等
!= ,ne不等
< ,lt小于

,gt | 大于
<= ,le | 小于等于
= ,ge | 大于等于
&& ,and | 逻辑与
|| ,or | 逻辑或
! ,not | 取反
empty | 测试是否空值,当值为null,空串,长度为0的数组,list,map集合返回true
表达式1?表达式2:表达式3:| 三元运算

empty运算的使用
${empty 表达式}

1.5 EL中的隐含对象

EL中定义了11个隐含对象,这些隐含对象可以很方便的获取一些开发中常用的对象,不需要事先定义,可以直接使用。

隐含对象描述
pageContext当前页面的pageContext,通过pageContext对象可以访问到jsp的九大内置对象
pageScopepage 作用域,可以获取pageContext域中的数据
requestScoperequest 作用域,可以获取request域中的数据
sessionScopesession 作用域,可以获取session域中的数据
applicationScopeapplication 作用域,可以获取ServletContext域中的数据
initParam获取上下文初始化参数(返回字符串)
param获取单个请求参数的值(返回字符串),类似request.getParameter();
paramValues获取多个请求参数的值(返回字符串集合),类似request.getParameterValues();
header获取HTTP 信息头(返回字符串)
headerValues获取多个HTTP 信息头(返回字符串集合)
cookie获取当前请求的Cookie值(返回Cookie对象)
如何使用这些隐含对象?
<!-- pageContext对象的使用 -->
${pageContext.request.servletName}
<!-- Scope对象的使用 -->
<!-- 
如果四个域对象中都有相同的key的时候,应该在使用前加上是哪个域调用的,
否则将会根据作用域的大小顺序从小到大调用(pageScrope域没有就找requestScope域,以此类推)
 -->
${requestScrope.key}
<!-- param对象的使用 -->
${param.username}
<!-- paramValues对象的使用 -->
${paramValues.hobby[0]}
<!-- initParam 对象的使用 -->
${initParam.username}
<!-- header 对象的使用 -->
${header.Connection}
${header['User-Agent']}
<!-- headerValues 对象的使用 -->
${headerValues['User-Agent'][0]}
<!-- cookie  对象的使用 -->
${cookie.JSESSIONID.name}

2、JSTL标签库

2.1 定义

JSTL(JSP Standard Tag Library) JSP标签库是一个不断完善的开放源码JSP标签库。需要我们自己去官网下载(自行根据操作系统和自己想要的JSTL版本号进行下载)。JSTL标签库下载地址

2.2 作用

EL表达式是为了代替JSP的表达式脚本,而标签库则是替换掉JSP的代码脚本,使整个JSP页面变得更加整洁。

2.3 组成

JSTL由五个不同功能的标签库组成

功能范围URI前缀
核心标签库(重点)http://java.sun.com/jsp/jstl/corec
格式化http://java.sun.com/jsp/jstl/fmtfmt
函数http://java.sun.com/jsp/jstl/functionsfn
数据库(不使用)http://java.sun.com/jsp/jstl/sqlsql
XML(不使用)http://java.sun.com/jsp/jstl/xmlx

2.4 使用

第一步:下载JSTL标签库的zip包并解压
第二步:将解压完后的JSTL包lib目录中的standard.jar 和 jstl.jar 文件拷贝到 /WEB-INF/lib/ 下。
第三步:在jsp中使用,记得得在头部加头部page指令导入jstl库,如导入核心标签库,
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

2.5 核心标签库

核心标签是最常用的 JSTL标签。引用核心标签库的语法如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

标签描述
<c:out>用于在JSP中显示数据,就像<%= … >
<c:set>用于保存数据
<c:remove>用于删除数据
<c:catch>用来处理产生错误的异常状况,并且将错误信息储存起来
<c:if>与我们在一般程序中用的if一样
<c:choose>本身只当做<c:when>和<c:otherwise>的父标签
<c:when><c:choose>的子标签,用来判断条件是否成立
<c:otherwise><c:choose>的子标签,接在<c:when>标签后,当<c:when>标签判断为false时被执行
<c:import>检索一个绝对或相对 URL,然后将其内容暴露给页面
<c:forEach>基础迭代标签,接受多种集合类型
<c:forTokens>根据指定的分隔符来分隔内容并迭代输出
<c:param>用来给包含或重定向的页面传递参数
<c:redirect>重定向至一个新的URL.
<c:url>使用可选的查询参数来创造一个URL

2.6 格式化标签

JSTL格式化标签用来格式化并输出文本、日期、时间、数字。引用格式化标签库的语法如下:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

标签描述
fmt:formatNumber使用指定的格式或精度格式化数字
fmt:parseNumber解析一个代表着数字,货币或百分比的字符串
fmt:formatDate使用指定的风格或模式格式化日期和时间
fmt:parseDate解析一个代表着日期或时间的字符串
fmt:bundle绑定资源
fmt:setLocale指定地区
fmt:setBundle绑定资源
fmt:timeZone指定时区
fmt:setTimeZone指定时区
fmt:message显示资源配置文件信息
fmt:requestEncoding设置request的字符编码

2.7 JSTL函数

JSTL包含一系列标准函数,大部分是通用的字符串处理函数。引用JSTL函数库的语法如下:

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

标签描述
fn:contains()测试输入的字符串是否包含指定的子串
fn:containsIgnoreCase()测试输入的字符串是否包含指定的子串,大小写不敏感
fn:endsWith()测试输入的字符串是否以指定的后缀结尾
fn:escapeXml()跳过可以作为XML标记的字符
fn:indexOf()返回指定字符串在输入字符串中出现的位置
fn:join()将数组中的元素合成一个字符串然后输出
fn:length()返回字符串长度
fn:replace()将输入字符串中指定的位置替换为指定的字符串然后返回
fn:split()将字符串用指定的分隔符分隔然后组成一个子字符串数组并返回
fn:startsWith()测试输入字符串是否以指定的前缀开始
fn:substring()返回字符串的子集
fn:substringAfter()返回字符串在指定子串之后的子集
fn:substringBefore()返回字符串在指定子串之前的子集
fn:toLowerCase()将字符串中的字符转为小写
fn:toUpperCase()将字符串中的字符转为大写
fn:trim()移除首尾的空白符

注:JSTL表签库的使用还应实践使用练习,以上只是列出有哪些标签

五、Cookie&Session

1、Cookie

Cookie 是存储在客户机的文本文件,它们保存了大量轨迹信息。是服务器通知客户端保存键值对的一种技术,每个Cookie的大小不超过4kb
Cookie 通常在 HTTP 信息头中设置,信息头中有一个Set-Cookie信息头,它包含一个或多个键值对,键值对会被编码为URL。有效期域是个指令,告诉浏览器在什么时候之后就可以清除这个 cookie。
如果浏览器被配置成可存储 cookie,那么它将会保存这些信息直到过期。如果用户访问的任何页面匹配了 cookie 中的路径和域名,那么浏览器将会重新将这个 cookie 发回给服务器。

1.2 Cookie的创建

第一步:创建一个Cookie对象

调用 cookie 的构造函数,使用一个 cookie 名称和值做参数,它们都是字符串。

Cookie cookie = new Cookie("key","value");

名称和值中都不能包含空格或者如下的字符:

[ ] ( ) = , " / ? @ : ;
第二步:设置有效期

调用 setMaxAge() 函数表明 cookie 在多长时间(以秒为单位)内有效。

cookie.setMaxAge(60*60*24); 
第三步:将 cookie 发送至 HTTP 响应头中

调用 response.addCookie() 函数来向 HTTP 响应头的Set-Cookie信息头中添加 cookie。这样客户端才能保存cookie。

response.addCookie(cookie);

1.3 Cookie的获取

获取 cookie需要调用 request.getCookies() 方法来获得一个Cookie 对象的数组,然后遍历这个数组,最后使用 getName() 方法和 getValue() 方法来获取每一个 cookie 的名称和值。

Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies){
	out.println("Cookie的key为"+cookie.getName()+",value为:"+cookie.getValue()+"<br/>");
}
// 查找cookie的方法
public static void findCookie(String name,Cookie[] cookies){
	if(name==null||cookies==null||cookies.length=0){
		return 0;
	}
	for(Cookie cookie:cookies){
		if(name.equals(cookie.getName())){
			return cookie;
		}
	}
	return null;
}

1.4 Cookie的修改

先创建一个和要修改的cookie名称一样的cookie,在构造器中将value设置为要修改完成后的内容,最后将其添加到响应头中,就可以实现Cookie的修改。

Cookie cookie = new Cookie("key","newvalue");
response.addCookie(cookie);

1.5 Cookie的删除

先获取要删除的cookie,然后将其的有效生存期设置为0,最后将cookie添加到响应头中,就可以实现Cookie的删除。

Cookie[] cookies = request.getCookies();
Cookie cookie = findCookie("key",cookies)
cookie.setMaxAge(0);
response.addCookie(cookie);

1.6 Cookie有效路径的配置

设置 cookie 的路径,可以有效地过滤哪些cookie可以发送给服务器,哪些不能。默认为当前页面目录下的所有 URL,还有此目录下的所有子目录。

Cookie cookie = new Cookie("key","value");
cookie.setPath(request.getContextPath+"/xxx");
cookie.addCookie(cookie);

2、Session

HTTP是无状态协议,这意味着每次客户端检索网页时,都要单独打开一个服务器连接,因此服务器不会记录下先前客户端请求的任何信息。
JSP利用servlet提供的HttpSession接口来识别一个用户,在服务器存储这个用户的所有访问信息Session依赖于SessionID,而SessionID存储在客户端的Cookie中

2.1 Session的创建和获取

Session的创建和获取和Cookie类似,Session不需要我们去创建,当我们第一次去调用Session时它就会去创建,第二次调用就是获取第一次创建的Session会话对象。我们通过isNew()方法判断Session是否是新创建出来的。true表示是,false表示不是。每一个会话都有一个唯一的ID值,可以通过getID()方法获取。

Integer visit_count = new Integer(1);
if(session.isNew()){
  out.println("第1次访问");
  session.setAttribute("visit_count",visit_count);
}else{
  visit_count = (Integer) session.getAttribute("visit_count");
  visit_count+=1;
  session.setAttribute("visit_count",visit_count);
  out.println("第"+session.getAttribute("visit_count")+"次访问");
}

2.2 Session的生命周期控制

一般情况下,当客户端和服务器建立连接时,session就创建了,session的默认超时时长是30分钟,即30分钟后会销毁。如果要更改默认时长可以在web.xml中修改。

<session-config>
    <session-timeout>20</session-timeout>
</session-config>

如何使Session销毁

  1. 可以直接断开与服务器的连接(关闭会话)
  2. 设置Session的超时时间(以秒为单位)使用setMaxInactiveInterval(int interval),传入值为正数时设定时长,负数或者0时为永不超时。设置个别Session的超时时长用这个方法。
  3. 调用invalidate()让当前对话马上超时无效。

2.3 Session的重要方法

方法方法描述
public Object getAttribute(String name)返回session对象中与指定名称绑定的对象,如果不存在则返回null
public Enumeration getAttributeNames()返回session对象中所有的对象名称
public long getCreationTime()返回session对象被创建的时间, 以毫秒为单位,从1970年1月1号凌晨开始算起
public String getId()返回session对象的ID
public long getLastAccessedTime()返回客户端最后访问的时间,以毫秒为单位,从1970年1月1号凌晨开始算起
public int getMaxInactiveInterval()返回最大时间间隔,以秒为单位,servlet 容器将会在这段时间内保持会话打开
public void invalidate()将session无效化,解绑任何与该session绑定的对象
public boolean isNew()返回是否为一个新的客户端,或者客户端是否拒绝加入session
public void removeAttribute(String name)移除session中指定名称的对象
public void setAttribute(String name, Object value)使用指定的名称和值来产生一个对象并绑定到session中
public void setMaxInactiveInterval(int interval)用来指定时间,以秒为单位,servlet容器将会在这段时间内保持会话有效

六、Listener监听器

监听器(Listener)是JavaWeb的三大组件之一,它在web中的作用是监听某种事物的变化,如servlet的创建,销毁等等。然后通过回调函数反馈给程序去做相应的处理。

例如监听ServletContext对象
先写一个监听器实现类

package com.linzhijie.Listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class servletListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext对象创建了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("servletContext对象销毁了");
    }
}

再到web.xml配置监听器

<listener>
    <listener-class>com.linzhijie.Listener.servletListener</listener-class>
</listener>

这样一个监听器就完成了。

七、Filter过滤器

1、定义

过滤器(Filter)是JavaWeb三大组件之一,它可以动态地拦截请求和过滤响应,以变换或使用包含在请求或响应中的信息。它常用于身份验证、加密、触发资源访问事件、日志记录和审核等等用途,是十分实用的一个接口。

2、过滤器的常用方法

过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:

方法描述
public void init(FilterConfig filterConfig)web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
public void doFilter (ServletRequest, ServletResponse, FilterChain)该方法完成实际的过滤操作,当客户端的请求与过滤器设置的 URL 匹配时,Servlet 容器将先调用过滤器的 doFilter 方法。FilterChain 用于访问后续过滤器。
public void destroy()Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

3、FilterChain过滤器链

即多个过滤器一起工作。所有的filter和目标资源都是默认执行在同一个线程中,当多个filter共同执行时使用的是同一个request对象。FilterChain.doFilter()方法是如果有下一个过滤器则执行下一个过滤器,否则执行目标资源。在多个filter过滤器执行的时候,执行的优先顺序取决于它们在web.xml中的上下顺序

4、Filter的拦截路径

  • 精确匹配:<url-pattern>/target.jsp</url-pattern>
  • 目录匹配:<url-pattern>/admin/*</url-pattern>
  • 后缀名匹配:<url-pattern>*.html</url-pattern>

Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在。

5、Filter过滤器的使用

第一步:创建Filter类

import javax.servlet.*;
import java.io.IOException;

public class loginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
		// 在这里可以获取init-param参数和初始设置
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 在这里执行过滤器要执行的操作
    }

    @Override
    public void destroy() {
		// 过滤器销毁
    }
}

第二步:在web.xml中配置过滤器

<!-- 指定过滤器   -->
<filter>
<!-- 用于为过滤器指定一个名字,该元素的内容不能为空。      -->
    <filter-name>loginFilter</filter-name>
<!-- 元素用于指定过滤器的完整的限定类名。      -->
    <filter-class>com.linzhijie.Filter.loginFilter</filter-class>
</filter>
<!-- 元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径 -->
<filter-mapping>
<!-- 子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字        -->
    <filter-name>loginFilter</filter-name>
<!-- 设置 filter 所拦截的请求路径(过滤器关联的URL样式)       -->
    <url-pattern>/.*</url-pattern>
</filter-mapping>

八、JSON、AJAX、i18n

1、JSON

1.1 定义

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。体积小,易解析。JSON也可以称为无类型对象。

1.2 格式

var 变量名 = {
	"key1":value, 	// Number类型
	"key2":"value", // 字符串类型
	"key3":[], 		// 数组类型
	"key4":{"key4-1":"value"}  // Json对象类型
	"key5":[{"key5-1":value},{"key6-1":value}] // Json数组	
};

1.3 在JS中的使用

如何访问JSON中的值
/* 1、Json的基本使用 */
// 创建一个json对象
var jsons = {
    "key1":1,
    "key2":"abc",
    "key3":[1,2,"a"],
    "key4":{"key4_1":1,"key4_2":"abc"},
    "key5":[{"name":"zhangsan","age":11},{"name":"li","age":13},{"name":"wangwu","age":17}]
};
// 访问jsons对象中的数据
// 这边有一个小细节,如果json对象中的key值命名包含关键字或者符号,则需要使用[]符号来进行取key值
alert(jsons.key1);
alert(jsons.key2);
alert(jsons); // [object Object]
alert(jsons.key3); // 1,2,a
alert(jsons.key3[1]); // 2
alert(jsons.key4); // [object Object]
alert(jsons.key4["key4-1"]); // 1
alert(jsons.key4[1])  // undefined
alert(jsons.key5[1].name); //li
// Json的遍历
for (var i=0;i<3;i++){
    alert(jsons.key3[i]);
}
alert(jsons.key4.key4_1);
alert(jsons.key4.key4_2);
for (var i=0;i<3;i++) {
    alert(jsons.key5[i].name + " " + jsons.key5[i].age);
}
转换JSON对象和字符串的方法
函数描述
JSON.stringify( json );可以把一个 json 对象转换成为 json 字符串
JSON.parse( jsonString );可以把一个 json 字符串转换成为 json 对象
// 将json对象转换为json字符串
var jsonString = JSON.stringify(jsons);
alert(jsonString);
/*
{"key1":1,
"key2":"abc",
"key3":[1,2,"a"],
"key4":{"key4-1":1,"key4_2":"abc"},
"key5":[{"name":"zhangsan","age":11},{"name":"li","age":13},{"name":"wangwu","age":17}]
}
*/

// 将json字符串转换为json对象
var jsonObj = JSON.parse(jsonString);
alert(jsonObj); // [object Object]
alert(jsonObj.key3) // 1,2,a

1.4 JSON在java中的使用

要使用json在java中使用需要导入一个第三方包———gson.jar
Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。
像是在JS中使用两个函数之前需要使用到的JSON对象。
它可以将一个 JSON 字符串转成一个 Java 对象,或者把一个JSON对象转换为JSON字符串

方法描述
toJson()java对象转换成json字符串
fromJosn()json字符串转换成java对象

json 在 java 中的操作。常见的有三种情况。

  1. java 对象和 json 的转换
  2. java 对象 list 集合和 json 的转换
  3. map 对象和 json 的转换

要把复杂的json字符串转换为java对象需要创建一个类继承TypeToken类,并把返回的类型当成TypeToken的泛型注入

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonTest {
    static class Person{
        int no;
        String name;
        public Person(int no, String name) {
            this.no = no;
            this.name = name;
        }

        public int getNo() {
            return no;
        }

        public void setNo(int no) {
            this.no = no;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    public static void main(String[] args) {
        // json操作一定要先创建一个gson对象
        Gson gson = new Gson();
        // 创建Person对象
        Person person = new Person(10, "zhangsan");
        
//        1、java 对象和 json 的转换
        // java对象转换成json字符串
        String personJson = gson.toJson(person);
        System.out.println("转换成json字符串为:"+personJson);
        // json字符串转换成java对象
        Person person1 = gson.fromJson(personJson, Person.class);
        System.out.println(person1);
        System.out.println("===================================================");
        
//        2、java 对象 list 集合和 json 的转换
        List<Person> personList = new ArrayList<>();
        for (int i=0;i<3;i++){
            personList.add(new Person(10+i,"zhangsan"+i));
        }
        // java对象转换成json字符串
        String personListJson = gson.toJson(personList);
        System.out.println("转换成json字符串为:"+personListJson);
        // json字符串转换成java对象
        List<Person> list = gson.fromJson(personListJson, new TypeToken<List<Person>>() {
        }.getType());
        System.out.println(list);
        System.out.println("===================================================");
        
//        3、map 对象和 json 的转换
        Map<Integer,Person> personMap = new HashMap<>();
        for (int i=0;i<3;i++){
            personMap.put(i,new Person(i,"lisi"+i));
        }
        // java对象转换成json字符串
        String personMapJson = gson.toJson(personMap);
        System.out.println("转换成json字符串为:"+personMapJson);
        // json字符串转换成java对象
        Map<Integer,Person> map = gson.fromJson(personMapJson, new TypeToken<Map<Integer, Person>>() {
        }.getType());
        System.out.println(map);
    }
}

在这里插入图片描述

2、AJAX

2.1 定义

AJAX(Asynchronous JavaScript and XML)异步的JavaScript和XML 是在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的技术。
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。而通过AJAX在后台与服务器进行少量数据交换,可以使网页实现异步更新。
例如注册账号时可以检测用户名是否被人注册过,如果被人注册过了会在旁边提示这个用户名已经被人注册过了,请您更改。

2.2 原生的AJAX请求

客户端:
第一步:创建 XMLHttpRequest 对象

var xmlHttpRequest = new XMLHttpRequest();

第二步:向服务器发送请求,调用open方法设置参数,send方法发送请求。
一般会在send方法之前绑定好onreadystatechange事件处理请求完成后的操作

xmlHttpRequest.open(method:String,url:String,async:boolean);
xmlHttpRequest.onreadystatechange = function () {
	if (xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
		
	}
}
xmlHttpRequest.send();

示例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>AjaxRequest</title>
</head>
    <script type="text/javascript">
        function ajaxRequest() {
            // 创建 XMLHttpRequest 对象
            var xmlHttpRequest = new XMLHttpRequest();
            // 调用open方法设置请求参数
            xmlHttpRequest.open("GET","http://localhost:8080/WebTest/ajaxServlet?action=JavaScriptAjax",true);
            xmlHttpRequest.open()
            // 绑定onreadystatechange事件
            xmlHttpRequest.onreadystatechange = function () {
                if (xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                    var jsonObj = JSON.parse(xmlHttpRequest.responseText);
                    document.getElementById("div0").innerHTML = "编号:"+jsonObj.no+"姓名:"+jsonObj.name;
                }
            }
            // 发送请求
            xmlHttpRequest.send();
        }
    </script>
<body>
    <button onclick="ajaxRequest()">ajax请求</button>
    <div id="div0"></div>
</body>
</html>

服务器端:
第三步:创建好类和方法处理请求
实例中的Person类自己创建

import com.linzhijie.Pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class AjaxServlet extends BaseServlet {
    /**
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void JavaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Person person = new Person(1,"张三");
        Gson gson = new Gson();
        String s = gson.toJson(person);
        resp.getWriter().write(s);
    }
}

这样一个原生的AJAX请求就完成了。

2.3 JQuery中的AJAX请求

JQuery中将ajax请求变得比原生的ajax请求简洁明了,省去了原生创建ajax请求的麻烦。其中有一点要注意的是在请求成功中的回调函数要加上参数data,这样才能获取到后端传过来的值。

$.ajax()方法
参数描述
url请求的地址
type请求的方式
data请求的参数,可以传字符串或者是json
success请求成功后的回调函数
dataType返回的数据类型
$.ajax({
    url:"http://localhost:8080/WebTest/ajaxServlet",
    // data:action="JQueryAjax",
    data:{action:"JQueryAjax",key:value},
    type:"GET",
    success:function (data) {
        $("#msg").html("ajax 编号:" + data.no + " , 姓名:" + data.name);
    },
    dataType:"json"
});
$.get()方法
参数描述
url请求的地址
data待发送的key/value参数
callback载入成功时回调函数
type返回内容的格式
$.get()方法是基于$.ajax()方法上对操作进行简化,减少了前面的参数名以及type需要传的请求方式。
$.get("http://localhost:8080/WebTest/ajaxServlet",{action: "JQueryGet"},function (data) {
   $("#msg").html("Get 编号:" + data.no + " , 姓名:" + data.name);
},"json");
$.post()方法

$post()方法和$get()方法同理

$.post("http://localhost:8080/WebTest/ajaxServlet","action=JQueryPost",function (data) {
    $("#msg").html("Post 编号:" + data.no + " , 姓名:" + data.name);
},"json");
$.getJSON()方法
参数描述
url请求的url地址
data发送给服务器的数据
callback成功的回调函数
$.getJSON()方法使用get请求返回JSON类型的内容格式,也是属于简化操作。
因此也是只需要三个参数。
$.getJSON("http://localhost:8080/WebTest/ajaxServlet","action=JQueryGetJson",function (data) {
    $("#msg").html("GetJson 编号:" + data.no + ",姓名:" + data.name);
});
serialize()表单序列化方法

serialize()方法可以把表单中所有表单项的内容全部都获取到,并以 name=value&name=value 的形式进行拼接。

$("#submit").click(function () {
     alert( $("#form01").serialize() );
     $.getJSON("http://localhost:8080/WebTest/ajaxServlet","action=JQuerySerialize&"+$("#form01").serialize(),function (data) {
         $("#msg").html("serialize 编号:" + data.no + ",姓名:" + data.name);
     })
 })

3、I18N

i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。但其实现在较为广泛使用的还是应该像苹果公司一样为每个国家创建一个相应的网站。
以下是i18n中的一些常用方法的使用。

import org.junit.Test;

import java.util.Locale;
import java.util.ResourceBundle;

public class i18nTest {
    @Test
    public void localeTest(){
        // 获取当前默认时区使用的语言
        Locale locale = Locale.getDefault();
        System.out.println(locale); // ZH_CN
        // 遍历所有的其他国家语言信息
//        for (Locale availableLocale:Locale.getAvailableLocales()){
//            System.out.println(availableLocale);
//        }
        // 获取中文中国常量的Locale对象
        System.out.println(Locale.CHINA);
        // 获取英文美国常量的Locale对象
        System.out.println(Locale.US);
    }
    @Test
    public void i18nTest(){
        // 得到我们需要用到的Locale对象
        Locale locale = Locale.CHINA;
        // 通过指定的basename和Locale对象读取相应的配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("i18n", locale);
        System.out.println("username:" + bundle.getString("username"));
        System.out.println("password:" + bundle.getString("password"));
        System.out.println("Sex:" + bundle.getString("sex"));
        System.out.println("age:" + bundle.getString("age"));
    }
}
<%@ page import="java.util.Locale" %>
<%@ page import="java.util.ResourceBundle" %>
<%@ 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="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		// 从请求头中获取Locale信息(语言)
		Locale locale = null;

		String country = request.getParameter("country");
		if ("cn".equals(country)) {
			locale = Locale.CHINA;
		} else if ("usa".equals(country)) {
			locale = Locale.US;
		} else {
			locale = request.getLocale();
		}

		System.out.println(locale);
		// 获取读取包(根据 指定的baseName和Locale读取 语言信息)
		ResourceBundle i18n = ResourceBundle.getBundle("i18n", locale);
	%>
	<a href="i18n.jsp?country=cn">中文</a>|
	<a href="i18n.jsp?country=usa">english</a>
	<center>
		<h1><%=i18n.getString("regist")%></h1>
		<table>
		<form>
			<tr>
				<td><%=i18n.getString("username")%></td>
				<td><input name="username" type="text" /></td>
			</tr>
			<tr>
				<td><%=i18n.getString("password")%></td>
				<td><input type="password" /></td>
			</tr>
			<tr>
				<td><%=i18n.getString("sex")%></td>
				<td>
					<input type="radio" /><%=i18n.getString("boy")%>
					<input type="radio" /><%=i18n.getString("girl")%>
				</td>
			</tr>
			<tr>
				<td><%=i18n.getString("email")%></td>
				<td><input type="text" /></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
				<input type="reset" value="<%=i18n.getString("reset")%>" />&nbsp;&nbsp;
				<input type="submit" value="<%=i18n.getString("submit")%>" /></td>
			</tr>
			</form>
		</table>
		<br /> <br /> <br /> <br />
	</center>
	国际化测试:
	<br /> 1、访问页面,通过浏览器设置,请求头信息确定国际化语言。
	<br /> 2、通过左上角,手动切换语言
</body>
</html>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ 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="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%--1 使用标签设置Locale信息--%>
	<fmt:setLocale value="${param.locale}" />
	<%--2 使用标签设置baseName--%>
	<fmt:setBundle basename="i18n"/>


	<a href="i18n_fmt.jsp?locale=zh_CN">中文</a>|
	<a href="i18n_fmt.jsp?locale=en_US">english</a>
	<center>
		<h1><fmt:message key="regist" /></h1>
		<table>
		<form>
			<tr>
				<td><fmt:message key="username" /></td>
				<td><input name="username" type="text" /></td>
			</tr>
			<tr>
				<td><fmt:message key="password" /></td>
				<td><input type="password" /></td>
			</tr>
			<tr>
				<td><fmt:message key="sex" /></td>
				<td>
					<input type="radio" /><fmt:message key="boy" />
					<input type="radio" /><fmt:message key="girl" />
				</td>
			</tr>
			<tr>
				<td><fmt:message key="email" /></td>
				<td><input type="text" /></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
				<input type="reset" value="<fmt:message key="reset" />" />&nbsp;&nbsp;
				<input type="submit" value="<fmt:message key="submit" />" /></td>
			</tr>
			</form>
		</table>
		<br /> <br /> <br /> <br />
	</center>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值