知识大纲:
一、掌握Web应用服务器
二、发布部署Web项目
三、JSP的基础学习
四、JSP的应用
一、Web应用及服务器
1、Web应用前提
在之前的页面开发中,我们所有信息的直接放置在网页上,通过浏览器即可查看,这样的页面无法与数据库交互,我们称之为 “静态网页” ,如果需要将数据实时更新,那么需要在此基础上做动态应用程序,且通过浏览器或客户端访问服务器的应用,我们称之为 “web应用 ”
2、Web应用的架构
2.1 客户端与服务器架构 :Client/ Server 例如大型网络游戏 (下载客户端程序并安装) 、QQ 、PC 微信 等
2.2 浏览器与服务器架构 : Browser/Server 例如 百度 ,京东,CSDN 等企业门户网站
2.3 移动设备端 : App应用 百度App 淘宝App等
区别 | C/S | B/S( 重点) |
---|---|---|
客户端请求 | 需要按照客户端 | 不需要安装,浏览器即可 |
访问速度 | 相对较快 | 相对更多依赖网速 稳定性受影响 |
页面美化 | cs特效更多 | 设计比较固化 |
维护成本 | 维护成本高 | 维护成本较低 |
无论使用哪一种架构都需要服务器支持,所以想要搭建一个系统,一定需要Web服务器的支持
3、Web服务器
3.1定义:
用于运行web应用程序的中间件 ,这里的中间件大多数是开源的
常用的Web服务器: WebLogic 、IIS 、Apache 、Apache Tomcat 、Nginx(服务器反向代理、静态资源服务器,分布式应用负载均衡)
初学者 建议使用 Apache Tomcat(简称Tomcat) 版本: Tomcat8, 9
来源: https://tomcat.apache.org/download-80.cgi Tomcat8.5.61 解压后目录
3.2 Tomcat目录结构
|- bin : 存放Tomcat启动、关闭等批处理文件, 启动服务 startup.bat 、startup.sh 关闭服务: shutdown.bat shutdown.sh catalina.bat 核心启动文件
|- conf: 存放配置文件
- server.xml (修改端口号) 默认端口号8080
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
- tomcat-user.xml 定义Tomcat的访问用户(角色和权限控制)
将如下代码放入在 中
<role rolename="manager-gui"/>
<user username="zhangsan" password="123456" roles="manager-gui"/>
- web.xml : Tomcat 的核心配置文件
|- lib : 存放Tomcat需要的 jar包
|- logs: 服务器运行的日志包 (默认一天一个日志文件)
|-temp : 存放用户临时文件
|-webapps: 存放项目的文件夹 (你的项目放在这里 )
|-work: 项目在运行期间,存放系统临时生成的文件 或 jsp生成的java类缓存文件
3.3 启动服务器
在启动之前需要确保已配置 JAVA_HOME 环境变量
%JAVA_HOME% C:Program FilesJavajdk1.8.0_144
启动服务 : 在bin目录下 startup.bat
访问服务器: http://localhost:8080/
访问自己的项目: 首先要确保项目在webapps下已存在
项目地址 : http://localhost:8081/项目名/页面名
二、IDEA中发布并运行项目
参考文档: https://www.cnblogs.com/guchenglin/p/10568279.html
步骤1: 新建一个Web Project 是Empty Project, 你的项目作为一个模块
步骤2 : 新增模块 Module (你的模块名 ,模块属于项目的)
注意这里需要 再选择一个 Web Application ,添加Web基础组件 会自动生成 web.xml 文件
新建好的项目如下:
步骤3: 新建 classes文件夹 和 lib文件夹 ,其中classes用于存放java文件的类文件
lib用于存放项目的jar包
步骤4: 配置Tomcat服务器 并发布项目
server的基本配置:
步骤5:启动服务器
访问地址 : http://localhost:8081/JSP01/
能正常打开,说明 服务器部署完成。
对于服务器启动 信息控制乱码解决方案:
三、 JSP基础
1、JSP的定义
在web项目中可以运行动态网页技术,JSP就是其中之一的动态网页技术
JSP 全称 Java Server Pages( Java 服务器端页面 ) ,用于开发动态网站
JSP 是 sun公司开发的基于 服务器端运行的 web技术 ,JSP的最终可生成对应的 Java类 ,
以.jsp结尾的文件
2、 JSP的基础元素中包括如下
2.1 jsp表达式:
以 <%= 开始 以%>结束, 可计算表达式的结果并输出
2.2 jsp小脚本 :
以<% 开始 以%> 结尾,中间可以写任意java片段代码
<%
int num1 =1;
int num2 =2;
System.out.println("两个数之和:"+(num1+num2)); //控制台输出
out.print("页面输出:"+(num1+num2)); // 等价于 <%=num1+num2%>
%>
2.3 jsp声明 :
以<%! 开头 以%>结尾; 声明主要用于定义变量和方法 ,不能直接写java片段
<%!
//定义全局变量
// 定义 方法
%>
2.4 jsp注释
<%-- 注释内容--> 与网页注释 ,区别在于网页注释可直接在浏览器源代码中查看 ,而jsp注释是服务端注释
2.5 jsp指令:
语法 以<%@开头 以%>结尾 , 包括3个指令
a、<%@ page 属性名=属性值 .... %> jsp页面指令,用于定义jsp页面的基本属性
常用属性: contentType = text/html;charset=UTF-8 设置页面编码格式和内容类型
pageEncoding :设置页面编码格式 (优先级高)
language="java" :设置脚本语言
import="java.util.*" :导入java的引入包和类 多个用逗号隔开,或者单独写多个import
errorPage=“error.jsp" 当页面异常,可跳转指定页面
isErrorPage="false" :判断是否为错误页面 ,用于错误页面的 异常对象使用
<%-- 当 指令中的属性 isErrorPage = true 时,该exception才可用--%>
<%--<%= exception.getMessage()%>--%>
b、 <%@ include file="url" %> 可以包含一个页面,可用于动态页面的嵌套。
<%-- 引入页面头--%>
<%@ include file="header.jsp"%>
该支持称为jsp的静态包含,在页面运行之前将两个页面合二为一。 注意两个页面中不能定义相同变量和方法。
c、<%@ taglib 属性名 = 属性值 > : 导入jstl标签的指令 后续使用是再演示
2.6 jsp动作:
动作格式 <jsp: 动作名 属性名= 属性值 />
例如:<jsp:include page="header.jsp"/> 也可以 包含指定页面,向比jsp include指令,它是在运行中动态查找该页面,并加重 ,会header.jsp预先编译 。
面试题:
面试题1: contentType与pageEncoding的区别?
pageEncoding : 表示页面的自身编码(UTF-8) ,contentType: 服务器响应给客户端时 发送的内容的编码格式(包括发送的内容格式)
练习: 定义一个jsp页面, 定义圆的半径,编写方法,计算圆的面积 和 周次,并在页面上输出
3、JSP的运行原理
JSP作为动态web页面,其自身在服务器生成一个对应的java文件
-
JSP源码分析得出结论
1、jsp页面在访问时,会自动转成 java类,其类名 jsp名称_jsp.jar (例如 hello.jsp -> hello_jsp.java) , 再编译成 class文件 里面所有的网页标签都通过 out写出流 发送给客户端 ,并设置文件内容类型mine格式为 text/html ,客户端才可以通过浏览器直接打开
2、 jsp中的 小脚本代码 全部放在 _jspService方法中
3、jsp中的 声明 全部是全局方法 或全局变量
4、jsp中所有的表达式 都是 基于_jspService方法中的 输出 out.print
我们还看到了 _jspService 方法中 提供了很多很多的对象 可直接使用, request 、response 、 out等
这些就是jsp中的内置对象
- JSP的运行原理
1、当客户端第一次发送请求时,由于请求的后缀.jsp , 服务器会自动将请求的jsp转义成java类并编译成class文件(第一访问较慢) ,存放在 C:Userswuyafeng.IntelliJIdea2018.2system omcatUnnamed_JavaWebProworkCatalinalocalhost 中 , 并执行 _jspService方法,向请求数据 通过 out对象响应给客户端
public void _jspService(final HttpServletRequest request, final HttpServletResponse response)
final PageContext pageContext;
HttpSession session = null;
final ServletContext application;
final ServletConfig config;
JspWriter out = null;
final Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
.........
}
2、当客户端再次访问该请求(.jsp结尾),服务器先检查是否存在对应的 java类,如果存在则直接更新内容后返回给服务器,如果不存在就重写 创建java类
四、JSP的内置对象
内置对象 定义:
在JSP中不需要 创建就可以直接使用的对象称为内置对象(隐式对象), 通过源码分析,JSP提供了9大内置对象
1、输入输出对象 : request 、 response 、 out
2、作用域通信对象: pageContext、 session 、 application (request既是输入输出对象也是通信对象 )
3、Servlet对象: config 、page (表示当前jsp页面对象 等于 this )
4、异常对象: exception
1、request 请求对象 ,response响应对象 :
一个正常的web交互流程: 客户端发送请求, 服务器作出相应 , 服务器可以接收到客户端 的请求数据,该数据的来源从request对象中获取
对象来源: javax.servlet.http.HttpServletRequest request
案例一: 模拟用户注册功能
<%
//设置请求编码格式
request.setCharacterEncoding("UTF-8");
// 获取客户端提交的数据 通过request内置对象
String username = request.getParameter("username"); // 通过请求参数的 name属性
String password = request.getParameter("password");
//获取重复密码
String repassword = request.getParameter("repassword");
//获取性别
String sex = request.getParameter("sex");
//获取
String[] hobby = request.getParameterValues("hobby");
//获取来源
String source = request.getParameter("source");
out.print("您注册的用户名:"+username);
out.print(" 密码:"+password);
out.print(" 重复密码:"+repassword);
out.print("性别:"+sex);
out.print("爱好:"+ Arrays.toString(hobby));
out.print("信息来源:"+source);
%>
如果本次注册 两次密码不一致 ,提示 注册失败 如果正确,则提示注册成功
页面与页面之间的跳转流程 :
关于重定向和转发的区别 :
共同点: 它们都具有页面跳转的功能
1、重定向由response完成, 转发由request完成
2、 重定向是一次新的请求,在客户端完成 有2次请求 (意味着不能获取表单初始提交的数据) , 转发是服务器内部的转发,只有一次请求,无论怎么跳转 都可以获取原始请求的参数
3、重定向可以跨域跳转,转发只能在服务内部访问资源
2、作用域通信对象
为什么会需要作用域通信对象?
由于浏览器与服务器之间是基于HTTP协议的交互 ,而HTTP是面向无连接协议(无状态)协议
所谓面向无连接就是浏览器发送请求,服务器响应完成,这个过程是独立的,等下一次再次发送请求时无服务无法知道该请求的状态,无法获取上一次的请求数据 ,如何服务器需要获取之前请求的数据,就迫切需要一个用于存储请求响应数据的“容器” ,这个“容器”存在服务器读书那 ,只要在指定范围类的操作,服务器就可以获取客户端的数据。
作用域通信对象根据使用的范围不同, 可分为 四类 :
作用域对象 作用范围
pageContext 存储的数据在当前页面中可以获取
request 一次请求
session 一次会话 (多次请求)
application 整个应用程序
这四个作用域都提供 setAttribute("key" ,Object) ; 设置 key -value
getAttribute("key") : 获取指定的key (一定满足对应的作用范围)
removeAttribute("key"); 删除容器中指定的 key
结论: 如果在页面跳转中 ,使用转发,那么你的作用域最少使用 request对象存 数据
如果在页面跳转中,使用重定向,那么你的作用域最少使用session对象 ,不能使用request,
转发:
存值: request.setAttribute(key,value)
request.getRequestDispatcher(url).forward(request,response);
重定向
存值 : session.setAttribute(key,value);
response.sendRedirect(url);
案例1:在线访问量
五、Servlet技术
1、Servlet定义
Servlet是由Java编写的用于处理客户端请求和响应的web服务器组件 ,Servlet是JavaWeb的基础组件
2、Servlet 特点
2.1 Servlet本事由Web容器(简称Servlet容器)管理
2.2 Servlet是比JSP更早的动态web网页技术
2.3 Servlet不能单独运行,需要由Servlet引擎来控制启动和调度
2.4 Servlet属于一个插件, 内部定制一些常用方法,例如 service ,init ,doGet ,doPost等
3、Servlet的使用
步骤一: 定义一个Java类 ,继承 HttpServlet类(抽象类,不能实例化)
步骤二: 重写该类的 doGet方法、doPost方法( 根据请求类型决定调用哪一个方法)
/**
*
* @param req 请求对象
* @param resp 响应对象 类似之前jsp的 request,response对象
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
// 设置响应给客户端的编码格式
resp.setContentType("text/html;charset=UTF-8");
//获取输出对象
PrintWriter out = resp.getWriter();
out.print("<h2>这是我的第一个Servlet程序</h2>");
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 由于不知道请求方式是 get 还是post 所以可以在两个方法中都执行相同的代码
this.doGet(req,resp);
}
步骤三: 在web.xml 中 配置Servlet的url请求 ,以便客户端可以直接方法
<!-- 配置MyServlet请求-->
<servlet>
<servlet-name>myServlet</servlet-name> <!--自定义名称,在整个项目中唯一 通常写类名首字母小写-->
<servlet-class>com.softeem.web.MyServlet</servlet-class> <!--Servlet的类路径 -->
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name> <!-- 指定的Servlet的name标签 -->
<url-pattern>/my</url-pattern> <!--一定以 / 开头,表示从当前项目下找Servlet -->
</servlet-mapping>
步骤四: 测试 请求
http://localhost:8081/Servlet01/my
Servlet的运行原理:
所有servlet类都由Servlet容器统一管理,每一个Servlet类在整个容器中只创建一个实例,默认将web.xml中的 url-pattern 作为key ,其value是对应的servletclass的路径
当客户端第一次请求路径是时/my ,Servlet容器会自动从已初始化的 key-value结构中 找 是否存在对应的key (/my) ,如果存在,则找到对应的servlet class类 ,并创建MyServlet实例,如果不存在返回404
再判断 该请求是get请求还是post请求,并执行doGet或doPost方法 ,最后响应给客户端。
当下一次请求该Servlet时,不需要再次创建对象,而直接执行doGet或doPost方法。
4、Servlet的生命周期
由于Servlet对象在整个Servlet容器中只有一个,我们需要研究Servlet从创建到销毁的整个过程,以便更深刻掌握Servlet组件, 这里 Servlet生命周期表示 它从创建到销毁的完整过程。
1、加载Servlet类 并实例化对象
2、初始化Servlet ,调用init方法
3、提供服务,调用service方法, 由service方法决定调用doGet 或doPost ,对于每一次请求都会执行service方法
4、销毁 ,调用destroy方法
//给该类添加Servlet配置 , urlPatterns指定访问路径,必须以/开头,如果有多个路径,可以指定数组形
//urlPatterns ="/circleServlet"
// loadOnStartup =正整数 ,表示容器启动就实例化和初始化 默认-1
@WebServlet(urlPatterns = {"/circleServlet","/circleServlet2"},loadOnStartup =1)
public class CircleServlet extends HttpServlet {
// 实例化
public CircleServlet(){
System.out.println(this.getClass().getName() +" =========");
}
@Override
public void init() throws ServletException {
System.out.println("Servlet正在初始化。。。。 init");
}
@Override
protected void service(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet 正在提供服务。。。。。 service");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("<h1>测试Servlet生命周期</h1>");
out.close();
}
@Override
public void destroy() {
System.out.println("正在调用 销毁 方法。。。。 destroy");
}
总结: 默认Servlet在第一次请求时,创建Servlet实例, 并执行init方法初始化信息 , 然后调用service方法 (内部调用doGet doPost方法)
当再次请求servlet 时,直接执行service方法
......
最后容器销毁时,自动执行destory方法 。
案例一: 使用JSP+Servlet完成登录案例
定义login.jsp 表单提交到 LoginServlet ,处理完毕之后,登录成功跳转 success.jsp ,登录失败返回login.jsp
5、Servlet的关系分布图
所属的包 javax.servlet.*
6、 Servlet中的核心对象 :
1、请求对象:
核心接口: javax.servlet.http.HttpServletRequest
实现类: javax.servlet.http.HttpServletRequestWrapper
它的父接口: javax.servlet.http.ServletRequest
常用方法:
1.1 请求头相关方法
getContextPath() : 请求的上下文路径 (/项目名 或者 /)
getCookies() : 返回客户端请求中包含的所有Cookie数组
getHeader() : 返回请求头部信息
getHeaderNames() : 返回请求头的名称的 枚举类型
getHeaders (name) : 返回指定的头信息的枚举类型
getMethod() : 返回请求的类型 (get/post)
getQueryString() : 返回url中?后面的查询参数,以字符串形式返回
1.2 客户端信息 (id,端口,主机名)
getRemoteAddr() : 获取客户端的IP
getRemotePort():获取客户端的端口
getRemoteHost() : 获取客户端的主机名
1.3 获取服务器信息
getLocalName() : 获取服务器的主机名
getLocalPosr() : 获取服务器的端口号
1.4获取请求参数相关的:
getParameter(name) : 获取请求参数名的value
getParameterValues() :获取请求参数的values值 ,
getParameterMap() : 获取请求参数的所有key-value ,返回Map集合
getParameterNames() : 获取请求参数的 name属性。 返回枚举
1.5获取请求的输入流 (用于文件上传的 IO流)
getInputStream() : 获取请求的数据流
getContentLength (): 获取请求的内容的长度
1.6 编码格式相关:
setCharacterEncoding("") : 获取请求参数
getCharacterEncoding()
1.7 与数据存储相关的
setAttribute(key,value)
getAttribute(key)
getAttributeNames() : 获取所有存储的 key的值 ,(根据key可以获取value)、
removeAttribute(key) : 移除指定的key
1.8与url相关
**getRealPath**() : 过时 , 获取当前请求servlet的 绝对路径
getRequestURI() : 请求地址的 部分路径
getRequestURL() : 请求地址的完整路径
getServletPath() : 请求的Servlet的路径
2、响应对象
用于处理客户端响应对象
核心接口: javax.servlet.http.HttpServletResponse
实现类: javax.servlet.http.HttpServletResponseWrapper
父接口: javax.servlet.ServletResponse
响应状态码:
200: 请求成功
302:指示已经将资源暂时地移动到了另一个位置
404:请求找不到资源
405:请求方法不对,例如get请求 服务器使用doPost()处理或者 post请求时,服务却使用doGet()处理
500:服务器内部错误
502:坏的url链接 无响应
503:服务器过载错误
常用方法:
getWriter() : 获取字符输出流
getOutput Stream() :获取响应字节输出流(输出图片对象,pdf 等)
addCookie(Cookie) : 添加cookie对象给客户端
getContentType(): 获取内容类型
setContentType(): 设置输出内容的类型
getCharacterEncoding(): 获取响应编码格式
setCharacterEncoding() : 设置响应编码格式
案例一: 使用响应对象 完成验证码功能
7、HttpSession对象
该对象表示服务器与客户端的会话对象 (session对象)
1、为什么需要会话对象?
由于http请求是无状态无连接协议,当客户端第一次访问服务器时,服务器给予响应之后就不再由任何联系 ,但是实际web项目中,服务器是需要记录客户端的访问和存储用户数据的,服务器也需要识别该客户端之前是否访问过。 所以就需要针对 每一个访问的客户端在服务器端创建一个存储数据的空间,并记录该用户信息,这就可以使用会话机制实现。
2、如何创建会话以及会话机制的实现原理
会话的实现原理:
基于Cookie对象的jsessionid变量 ,当第一次访问服务器时,请求头中的jsessionid为空,服务器会创建新会话并通过响应头返回给客户端,并返回jsessionid。 这里可以存储用户数据
当下一次访问是,客户端将请求头的jsessionid 访问服务器,服务器先判断该jsession是否过期,如果已过期,又重写创建会话对象并返回,如果服务器存在jseessionid的对象,则可直接获取该对象中用户存储的数据。
这样可以保证客户端与服务器之间来回交互并识别该用户数据。
问题: Session的会话实现机制是依赖Cookie的吗? 如果客户端禁用Cookie还能使用Session吗?
回答:是依赖Cookie ,但是如果Cookie禁用也能正常使用Session ,可以将jsessionid 通过url传参的方法解决。 例如: url?jsession=6383CB7CF767B090DB6E0D78B75E1996
案例1、使用session完成7天免登录
3、Session过期时间修改的三种方式
Session的默认过期时间是30分钟, 可以修改该时间
方式1: 在当前类的代码中修改,作用范围只对访问当前类的会话生效
HttpSession session = req.getSession();
session.setMaxInactiveInterval(秒 )
方式2: 在当前项目的web.xml中配置 session的过期时间 ,作用范围对整个项目有效
<!-- 修改当前项目的session时间-->
<session-config>
<!-- 单位是分钟-->
<session-timeout>30</session-timeout>
</session-config>
方式3:在web服务器的核心配置文件中设置session过期时间 ,作用范围对当前服务器下的所有项目有效
<session-config>
<session-timeout>30</session-timeout>
</session-config>
8、Servlet的配置对象和Servlet的上下文对象
Servlet的配置对象用于配置当前servlet的参数,获取参数 ,作用范围只对当前Servlet有效
而Servlet的上下文对象用于配置所有Servlet的参数 ,获取参数,作用范围是针对当前项目的所有Servlet对象 ,。
Servlet配置对象来源: javax.servlet. ServletConfig -> 等价于 JSP的内置对象 config
<servlet>
<servlet-name>testConfigServlet</servlet-name>
<servlet-class>com.softeem.web.TestConfigServlet</servlet-class>
<!-- 设置配置参数-->
<init-param>
<param-name>username</param-name>
<param-value>zhangsan</param-value>
</init-param>
</servlet>
// 获取当前Servlet的配置对象
ServletConfig config =this.getServletConfig();
// 获取当前Servlet存储的参数
String username = config.getInitParameter("username");
System.out.println("获取当前类配置信息 username :"+ username );
Servlet上下文对象来源: javax.servlet.ServletContext -> 等价于JSP的内置对象 application
案例: 初始化参数
<!-- 配置上下文参数 配置在 servlet节点的外面 -->
<context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
</web-app>
// 2、获取上下文的配置对象.getContextPath()
ServletContext context = this.getServletContext();
//上下文对象用于 与 Servlet 容器通信,可存储公共的信息 和 获取公共信息
String encoding = context.getInitParameter("encoding");
System.out.println( "获取上下文配置信息 encoding:" + encoding);
// 存储信息
context.setAttribute("encode",encoding);
9、Cookie对象
Cookie是存储在浏览器端的一小段文本,当服务器响应给客户端时,服务器存储在浏览器端的数据保存在Cookie中, 用于服务器对浏览器的识别
Cookie的应用场景
1、记住用户
2、缓存用户浏览记录(url)
3、免登录功能
Cookie的创建和使用
来自javax.servlet.http.Cookie对象 ,存储字符串信息
Cookie cookie = new Cookie(String name , String value);
// 由响应对象返回给客户端
resp.addCookie(cookie);
常用方法: getName() 获取当前Cookie的 name
getValue() 获取当前Cookie的value
setMaxAge(秒) 设置Cookie的最大存活时间, 到达时间后自动销毁
正数: 指定时间后Cookie过期
负数或0 : 在浏览器端不写Cookie ,浏览器关闭Cookie消失
getMaxAge() :获取Cookie的最大存活时间
获取请求Cookie对象
Cookie [] cks = req.getCookies() ;
// 由于浏览器中可存储多个Cookie
案例 Cookie完成 “记住我” 功能
页面:
// 登录 提交
$("#btnLogin").click(function(){
// 获取用户名
// 密码
// 记住我
var uname = $("[name=username]").val();
var password = $("[name=password]").val();
var remember = $("[name=remember]").val();
// 判断 是否选中 选中就是 yes 不选中 其他
if($("[name=remember]").is(":checked")){
remember='yes';
}
//发送ajax请求
$.ajax({
type:'post',
url:'login2Servlet',
data:"uname="+uname+"&password="+password+"&remember="+remember,
success:function(res){
// 可以接收一个json对象
if(res.status=='0'){
alert(res.msg);
location.href="success.jsp";
}else{
alert(res.msg);
}
},
dataType:"JSON"
});
});
if("admin".equals(uname) && "123".equals(password)){
// 记住我功能
if("yes".equals(remember)){
//创建Cookie 将Cooki给 客户端
Cookie ck1 = new Cookie("username",uname);
//设置ck的生命周期
ck1.setMaxAge(5*60);;
Cookie ck2 = new Cookie("remember","yes");
ck2.setMaxAge(5*60);
//响应给客户端
resp.addCookie(ck1);
resp.addCookie(ck2);
// 这里也可以使用Cookie 完成免登录功能 (7天免登录 ) 设置Cookie的生命周期7天
}else{
Cookie ck2 = new Cookie("remember","no");
ck2.setMaxAge(5*60);
resp.addCookie(ck2);
}
// {"status":"0","msg":"登录成功"}
out.print("{"status":"0","msg":"登录成功"}");
}else{
//{"status":"1","msg":"用户名或密码错误"}
out.print("{"status":"1","msg":"用户名或密码错误"}");
}
该代码可以写在 login页面的前置Servlet中
<% // 获取客户端请求的Cookie
String username="";
String remember ="";
Cookie [] cks = request.getCookies();
if(cks !=null){
for(Cookie ck : cks){
//获取所有的name value
if(ck.getName().equals("username")
&& !"".equals(ck.getValue())){
username = ck.getValue();
}
if(ck.getName().equals("remember")){
remember = ck.getValue();
}
// 如果免登录 直接跳转 success.jsp
}
}
if("no".equals(remember)){
username="";
}
%>
面试题:
Cookie和Session的区别
1、 Cookie存储在客户端, Session存在服务器端
2、Cookie只能存文本字符串 ,Session可以存对象
3、Session的实现机制是依赖Cookie, 如果Cookie被禁用,可以使用URL传参的方式启动Session
4、Cookie 不安全 用于存在不太重要的信息 ,Session 安全 存储重要信息,session会占用服务器资源
作业1 :完成 Cookie的7天免登录功能
六、过滤器
1、过滤器的定义
在Javaweb的请求响应中,提供一种功能可以在请求到达之前和 响应客户端之后 执行某些任务 , 可通过过滤器组件定制
过滤器用于对web请求进行拦截并处理任务 ,对响应进行拦截处理
过滤器的应用场景:
1、统一设置请求、响应的字符编码格式
2、身份验证,对请求用户拦截并验证是否登录
3、敏感字符过滤 (用户提交数据时,过滤广告,敏感字符等)
4、免登录(以前写在jsp的页面上,可以写在过滤器中)
2、如何实现过滤器
步骤1:创建一个过滤器类 实现接口 (javax.servlet.Filter)
步骤2: 重写doFilter方法
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
// 过滤器一旦拦截到该请求 则直接doFilter方法,
System.out.println("正在执行拦截任务。。。。 ");
//将请求转递给下一个过滤器 ,如果没有下一个过滤器 就到达目标方法servlet中
filterChain.doFilter(servletRequest,servletResponse);
}
步骤3:配置拦截的请求
@WebFilter(urlPatterns = "/login2Servlet") // 只是拦截请求是 login2Servlet
public class MyFilter implements Filter {
案例1: 设置请求编码和响应编码
package com.softeem.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* ClassName: EncodingFilter
* Description:
* date: 2020/12/16 16:42
*
* @author wuyafeng
* @version 1.0 softeem.com
*/
@WebFilter("/*") // // /* 表示过滤所有请求,这里包括.jsp 和servlet 和静态资源
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
//设置编码格式
servletRequest.setCharacterEncoding("UTF-8");
servletResponse.setContentType("text/html;charset=UTF-8");
HttpServletRequest req = (HttpServletRequest)servletRequest;
System.out.println("正在设置请求响应编码"+ req.getRequestURI());
// 将请求传递给下一个过滤器,没有下一个到达目标servlet
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
案例2: 设置登录验证
将图书管理系统 增加用户验证功能 如果没有登录则不能到达管理页面
图书管理两张表
用户表、图书表