Cookie类
概念:Cookie是保存在客户端的小文本,保存位置分为两种
1.保存在客户浏览器的1所占内存中,关闭浏览器,就不再存在
2.保存在客户pc机的硬盘上,设置有效时间,超过时间后消失
常见应用
1.简化登录:很多网站在登陆时,可以选择多久之内不需要登录,在选择时间内不用登录也可以到欢迎界面
2.记录浏览器记录:购物网站,每次登录后,会看到曾经浏览过的商品信息
使用原则
1.不用cookie保存对保密性要求高的信息,例如银行卡号密码等
2.不用cookie实现必要功能,放在cookie被删除后出现错误
可以说:cookie用来实现“”锦上添花”的功能,也就是说,一旦cookie禁止或者被删除,应用依然能正常运行
案例演示
//login。jsp
<%@page import="org.apache.jasper.tagplugins.jstl.core.ForEach"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
/*获取Cookie数组*/
Cookie[] cookies=request.getCookies();
Cookie accountCookie=null;
Cookie pwdCookie=null;
/*循环数组查找账号和密码的Cookie*/
if(cookies!=null){
for(Cookie c:cookies){
if("account".equals(c.getName())){
accountCookie=c;
}
if("pwd".equals(c.getName())){
pwdCookie=c;
}
}
}
//判断Cookie是否存在
if(accountCookie!=null&&pwdCookie!=null){
//将Cookie的数据提交到LoginServlet
request.getRequestDispatcher("LoginServlet?account="+accountCookie.getValue()+"&pwd="
+pwdCookie.getValue()).forward(request, response);
}
%>
<%if(request.getAttribute("msg")!=null) {%>
<%=request.getAttribute("msg") %>
<%} %>
<form action="LoginServlet">
<div>
<input type="text" name="account" placeholder="请输入账号">
</div>
<div>
<input type="password" name="pwd" placeholder="请输入密码">
</div>
<div>
<input type="checkbox" name="time" value="1">一天內免登录
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
</body>
</html>
//success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%if(request.getAttribute("msg")!=null) {%>
<%=request.getAttribute("msg") %>
<%} %>
<div style="float:right">
<button onclick="window.location.href='LogoutServlet'">退出登录</button>
</div>
<div>
欢迎,<%=request.getAttribute("account") %>
</div>
<a href="showAll.jsp">点击一览</a>
</body>
</html>
//LoginServlet
package demo.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String account=request.getParameter("account");
String pwd=request.getParameter("pwd");
if("tom".equals(account)&&"123".equals(pwd)) {
// 免登陆一般在登录成功后设置
if(request.getParameter("time")!=null) {
// Cookie保存的信息有两个:账号、密码
Cookie accountCookie=new Cookie("account", account);
Cookie pwdCookie=new Cookie("pwd", pwd);
// 设置Cookie的有效时长
int time=Integer.parseInt(request.getParameter("time"));
accountCookie.setMaxAge(time*24*3600);
pwdCookie.setMaxAge(time*24*3600);
// 将Cookie添加到相应中
response.addCookie(accountCookie);
response.addCookie(pwdCookie);
}
request.setAttribute("msg", "登录成功");
request.setAttribute("account", account);
request.getRequestDispatcher("success.jsp").forward(request, response);
}
else {
request.setAttribute("msg", "登录失败");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
//LogoutServlet
package demo.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LogoutServlet
*/
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LogoutServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//实现退出登录效果
// 实际上就是使Cookie失效
// 方式1:不设置有效时长,关闭浏览器自动失效
// 方式2:将现成的Cookie设置为空对象,再设置有效时长为0
Cookie accountCookie=new Cookie("account", null);
Cookie pwdCookie=new Cookie("pwd", null);
pwdCookie.setMaxAge(0);
accountCookie.setMaxAge(0);
response.addCookie(pwdCookie);
response.addCookie(accountCookie);
request.setAttribute("msg", "退出成功");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Session会话
概念:客户端向服务端发送请求,服务器端接受请求并生成响应返回给客户端,客户端对服务器端这样一次连续的调用过程,被称为会话(session)。
会话的典型应用
登录访问控制
某些资源不能直接访问,只对登录用户开放
实现方法:把登录后的信息保存到会话中,访问资源前,前查看会话中的登录信息,如果存在,则允许访问,否则跳转到登录页面
问题:登录信息能否保存到请求中?
不可以,因为请求的有效范围很小,除了请求转发外,都生成新的请求。而会话有效返回大,在一次会话中,服务器端与一个客户端只能维护一个会话对象
案例演示:
//success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 获取session中设置的属性 -->
<div>
欢迎,<%=session.getAttribute("account") %>
</div>
<a href="showAll.jsp">点击一览</a>
</body>
</html
//test01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 控制访问 -->
<%if(session.getAttribute("account")==null){
request.setAttribute("msg", "还未登录,请登录后访问");
request.getRequestDispatcher("login01.jsp").forward(request, response);
}%>
张三,只有登录才能访问
</body>
</htm
//Login01Servlet
package demo.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class Login01Servlet
*/
@WebServlet("/Login01Servlet")
public class Login01Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Login01Servlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String account=request.getParameter("account");
String pwd=request.getParameter("pwd");
if("tom".equals(account)&&"123".equals(pwd)) {
// 登录成功后,将登陆信息保存到会话中
// 1.获取会话对象
HttpSession session=request.getSession();
// 2.调用setAttribute方法将登录信息传入
session.setAttribute("account", account);
request.getRequestDispatcher("success01.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
ServletContext(应用上下文)
概念:MyEclipse的每一个Web Project,运行时都部署在Tomcat下,称为一个应用,部署后,启动Tomcat将为每一个应用创建一个对象,这个对象称为上下文对象。
一个应用有且只有一个上下文对象,有容器创建,并保存在容器中
上下文的作用
1.上下文对象类似一个全局变量,在整个应用中有效
2.利用上下文对象,可以实现多个用户之间的数据共享
监听器
概念:
监听器是为了监听事件并处理的,所以要理解监听器的概念,首先要理解事件的概念。
某些操作总会触发一种事件发生,如启动或关闭容器、创建或销毁会话等。当发生了某种事件,容器将创建对应的事件类对象。也就是说,API中已经定义好了事件的类型,容器进行了实现,当某些特定操作发生时,会自动触发相应的事件。
Servlet API中定义了6种事件类型
ServletContextEvent:该类表示上下文事件,当应用上下文对象发生改变,如创建或销毁上下文对象时,将触发上下文事件。
ServletContextAttributeEvent:该类表示上下文属性事件,当应用上下文的属性改变,如增加、删除、覆盖上下文中的属性时,将触发上下文属性事件。
ServletRequestEvent:该类表示请求事件,当请求对象发生改变,如创建或销毁请求对象时,触发请求事件。
ServletRequestAttributeEvent:该类表示请求属性事件,当请求中的属性改变,如增加、删除、覆盖请求中的属性时,触发请求属性事件。
HttpSessionEvent:该类表示会话事件,当会话对象发生改变,如创建或销毁会话对象,活化或钝化会话对象时,将触发会话事件。
HttpSessionBindingEvent:该类表示会话绑定事件,当会话中的属性发生变化时,如增加、删除、覆盖会话中的属性时,将触发会话绑定事件。
8种监听器接口
Servlet API中定义了8种监听器接口,用来监听不同的事件类型
ServletContextListener:上下文监听器,监听ServletContextEvent事件。
ServletContextAttributeListener:上下文属性监听器,用来监听ServletContextAttribute事件。
ServletRequestListener:请求监听器,监听ServletRequestEvent事件。
ServletRequestAttributeListener:请求属性监听器,用来监听ServletRequestAttributeEvent事件。
HttpSessionListener:会话监听器,监听HttpSessionEvent。
HttpSessionActivationListener:会话活化监听器,监听HttpSessionEvent事件。
HttpSessionAttributeListener:会话属性监听器,监听HttpSessionAttributeEvent事件。
HttpSessionBindingListener:会话绑定监听器,监听HttpSessionAttributeEvent事件。
事件与监听器的关系
事件对象是容器创建的,触发的条件也已经定义好。例如,只要容器关闭,启动,就会触发ServletContextEvent ,容器会创建该类型对象。
当事件发生后,容器会寻找监听器来处理该事件。监听器需要程序员自定义并配置,然而监听器的类型已经定义好。例如,当发生了ServletContextEvent事件后,只能用ServletContextListener监听器监听。
案例演示:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>Stu20230320</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
<!-- 设置上下文初始化参数 -->
<context-param>
<param-name>level</param-name>
<param-value>1</param-value>
</context-param>
<!-- 配置监听器 -->
<listener>
<listener-class>demo.listener.VisitCountListener</listener-class>
</listener>
</web-app>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="LoginServlet">
<div>
<input type="text" name="account" placeholder="请输入账号">
</div>
<div>
<input type="password" name="pwd" placeholder="请输入密码">
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
</body>
</html>
session.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
欢迎,<%=session.getAttribute("account") %>
<!-- jsp内置对象application应用上下文 -->
您是第<%=application.getAttribute("count") %>位访问本网站的用户<br>
您当前等级为<%=application.getInitParameter("level") %>
</body>
</html>
package demo.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class DBUtils {
// 获取Connection对象(数据库连接相关数据可通过参数控制)
public static Connection getConn(String driver,String url,String user,String pwd) {
try {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url,user,pwd);
return conn;
}catch(Exception e) {
return null;
}
}
// 固定数据库连接参数获取Connection对象
public static Connection getConn() {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mysql2209?useUnicode=true&characterEncoding=utf8",
"root",
"root"
);
return conn;
}catch(Exception e) {
return null;
}
}
// 关流
public static void close(Connection conn,PreparedStatement ps,ResultSet rs) {
try {
if(rs!=null)rs.close();
if(ps!=null)ps.close();
if(conn!=null)conn.close();
}catch(Exception e) {
}
}
}
package demo.controller;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String account=request.getParameter("account");
String pwd=request.getParameter("pwd");
if(account!=null&&!"".equals(account)&&pwd!=null) {
// 1.获取ServletContext对象(应用上下文)
ServletContext ctxt= this.getServletContext();
// 2.每次登录都要在原有的基础上加1
int count=0;
// 判断应用上下文中是否存在count属性
if(ctxt.getAttribute("count")!=null) {
count=Integer.parseInt(ctxt.getAttribute("count").toString());
}
count++;
ctxt.setAttribute("count", count);
System.out.println(count);
HttpSession session=request.getSession();
session.setAttribute("account", account);
request.getRequestDispatcher("session.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
package demo.listener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
//应用上下文监听器,--用于应用上下文对象创建和销毁事件触发的监听器
import javax.servlet.ServletContextListener;
import demo.common.DBUtils;
public class VisitCountListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 读取上下文对象属性中的count值,写入到mysql2209库的visit表中
// 表只维护count一个字段的这个值(修改)
// 获取其中的count属性值
ServletContext ctxt=sce.getServletContext();
// 2.获取其中的count值
int count=Integer.parseInt(ctxt.getAttribute("count").toString());
// 通过jdbc连接将改值修改到表中
Connection conn=DBUtils.getConn();
PreparedStatement ps=null;
String sql="update visit set count=?";
try {
ps=conn.prepareStatement(sql);
ps.setInt(1, count);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
DBUtils.close(conn, ps, null);
}
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// 读取数据库表中的count值,将值直接存到上下文对象的属性中
Connection conn=DBUtils.getConn();
PreparedStatement ps=null;
ResultSet rs=null;
String sql="select*from visit";
try {
ps=conn.prepareStatement(sql);
rs=ps.executeQuery();
if(rs.next()) {
int count=rs.getInt(1);
ServletContext ctxt= sce.getServletContext();
ctxt.setAttribute("count", count);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DBUtils.close(conn, ps, rs);
}
}
}
过滤器
概念和作用:
实际应用中,一个应用下会有很多页面需要访问控制,目前的实现方案中,需要在每一个需要访问控制的文件中加上判断代码,代码将很冗余,如果需要修改,也比较繁琐。除了访问控制这样的功能外,Web应用中还会有其他这种需求,例如权限校验、加密处理等。都需要在若干个文件中编写类似的代码。
过滤器可以解决这个问题,可以用来进行通用处理,而不需要在多个文件中写相同代码
过滤器相关的API
Servlet API 中,与过滤器有关的API共有三个接口,分别是
Filter,FilterChain,FilterConfig
Filter接口
Filter接口是过滤器类必须实现的接口,该接口中有三个方法。
init(FilterConfig filterConfig):该方法是对filter对象进行初始化的方法,仅在容器初始化filter对象结束后被调用一次。参数FilterConfig可以获得filter的初始化参数(初始化参数参见下面章节)。
doFilter(ServletRequest request, ServletResponse response, FilterChain chain):该方法是filter进行过滤操作的方法,是最重要的方法。过滤器实现类必须实现该方法。方法体中可以对request和response进行预处理。其中FilterChain可以将处理后的request和response对象传递到过滤链上的下一个资
destroy():该方法在容器销毁过滤器对象前被调用。
案例演示:
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<%if(request.getAttribute("msg")!=null){ %>
<%=request.getAttribute("msg").toString() %>
<%} %>
<body>
<form action="../LoginServlet" method="post">
<input type="text" name="account" placeholder="请输入账号">
<input type="submit" value="登录">
</form>
</body>
</html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
登录成功,欢迎<%=session.getAttribute("account") %>
</body>
</html>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
通道未开启,请在开启时间查询成绩
</body>
</html>
package demo.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class LoginFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("doFilter");
// 实现访问控制,当未登录时,无法访问test文件夹中的资源
// 先获取会话对象session
// 将ServletRequest request向下转型HttpServletRequest req
HttpServletRequest req=(HttpServletRequest)request;
HttpSession session=req.getSession();
// 2.获取session中的登录信息
if(session.getAttribute("account")==null) {
// 若未登录则跳转回登录页面
request.setAttribute("msg", "未登录");
request.getRequestDispatcher("../login.jsp").forward(request, response);
}
// 处理后的请求和响应发送到资源链上的下一个资源
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("destroy");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init");
}
}
package demo.filter;
import java.io.IOException;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CET4Filter implements Filter{
//如果deFilter方法要使用过滤器初始化参数,则需要将该属性设置为全局变量
private int start;
private int end;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
// 实现在早8时到晚8时可以访问
Date date=new Date();
int nowHour=date.getHours();
if(nowHour>end||nowHour<start) {
HttpServletResponse req=(HttpServletResponse)response;
req.sendRedirect("../error.jsp");
}
// chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
// 获取过滤器初始化参数
start=Integer.parseInt(filterConfig.getInitParameter("start"));
end=Integer.parseInt(filterConfig.getInitParameter("end"));
}
}
package demo.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理post请求中文乱码问题
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("utf-8");
String account=request.getParameter("account");
System.out.println(account);
if(account!=null&&!"".equals(account)) {
HttpSession session=request.getSession();
session.setAttribute("account", account);
response.sendRedirect("success.jsp");
}else {
request.setAttribute("msg", "用户名不能为空");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>Stu20230321</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<!-- 将过滤器加载到容器中 -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>demo.filter.LoginFilter</filter-class>
</filter>
<!-- 配置filter映射,设置过滤的路径 -->
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/test/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CET4Filter</filter-name>
<filter-class>demo.filter.CET4Filter</filter-class>
<init-param>
<param-name>start</param-name>
<param-value>8</param-value>
</init-param>
<init-param>
<param-name>end</param-name>
<param-value>20</param-value>
</init-param>
</filter>
<!-- 配置filter映射,设置过滤的路径 -->
<filter-mapping>
<filter-name>CET4Filter</filter-name>
<url-pattern>/cet4/*</url-pattern>
</filter-mapping>
</web-app>
jsp的四种注释
1.<!-- HTML注释,会被out.write输出到客户端,是静态页面注释 -->
2.<%-- jsp注释,在jsp执行时不会经过翻译,所以翻译后的java文件中不会出现该注释内容 --%>
3.<%//脚本单行注释 ,会被翻译,成为翻译后java文件的注释%>
4.<%/*脚本多行注释*/ %>
jsp声明:
<!--以下写法是jsp的声明,多用于声明方法和全局变量,该声明的代码在翻译时会翻译到java类中而不是_jspService()中 -->
jsp9大内置对象
1当前页面对象.page
2上下文.pageContext
3初始化.config
4输出当前页面数据.out
5请求.request
6响应.response
7会话.session
8应用上下文.application
9异常.exeception
jsp标准动作
标准动作中的请求转发方式跳转,默认情况下允许拼接参数,但参数值要符合unicode编码,在0-255中,如果要传递中文,需要先将请求的编码格式设置为Utf-8
<%request.setCharacterEncoding("utf-8"); %>
<jsp:forward page="test4.jsp?comName=滕泰科技"></jsp:forward>
动态包含,page属性可以设置url资源路径从而可以拼接参数,与静态包含的区别在于动态包含发生在请求阶段,而静态包含发生在翻译阶段
参数标准动作,往往作为forward和include子动作,属性包括name和value对于的参数的键和值,如果需要传递中文,则需要将请求编码集设置为utf-8
<jsp:include page="test3.jsp">
<jsp:param value="滕泰科技" name="comName"/>
</jsp:include>
El表达式
作用:简化jsp的脚本语言
EL内置对象
1.当前页面范围内:pageScope
<%pageContext.setAttribute("name", "tom"); %>
${pageScope.name }<br>
2.请求范围内:requstScope,接收请求里面的属性
<%User user=(User)request.getAttribute("user");
${requestScope.user.name }
3.会话范围内:sessionScope
${sessionScope.user.name }
4.应用上下文范围内:applicationScope
${applicationScope.user.name }
5.不指定范围,直接从属性名开始写,如果出现重名属性,则从最小的开始显示,若找到applicationScope时还没有相应的属性名,则什么都不显示
${user.name }
与请求头相关的内置对象
1.header:输出一个请求头中的值
2.headerValues:返回一个数组,例如cookie【】
JSESSIONID:${headerValues.cookie[0] }
获取kookie的内置对象
${cookie.JSESSIONID.value }
获取应用上下文初始化参数的内置对象
${initParam.path }
pageContext内置对象,可以调用符合pageContext中所有的getXXX()
${pageContext.request }
${pageContext.request.remoteAddr }
JSTL
概念:
JSTL也是一套标签库,不过是是厂商已经定义好的标签库,程序员只要使用即可。有了“自定义标签”的基础,理解、使用JSTL相对比较容易。
JSTL的本质及使用方法,与自定义标签完全相同
1.使用<%@taglib%>导入tld文件
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
2.通过前缀调用标签,指定属性进行使用
作用:
1.JSTL是一套厂商已经定义好的标签,所以JSTL的作用就是用来减少JSP中的Java代码,提高Java代码的重用性。
2.使用JSTL时,往往需要和EL一起使用,EL用来为JSTL属性赋值,用来在JSTL的标签体中显示数据等。
3.如果没有EL,JSTL的作用将大打折扣 ,当然,如果没有JSTL,EL也难发挥作用。
JSTL和EL使用实例:
%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:if test="${list!=null}">
<table border="1">
<tr>
<th>员工编号</th>
<th>员工姓名</th>
<th>员工工资</th>
</tr>
<c:forEach items="${requestScope.list}" var="emp">
<tr>
<td>${emp.id}</td>
<td>${emp.name}</td>
<td>${emp.sal}</td>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>
JSTL常用标签
C;if 、C:choose 判断语句
如果使用c:if分支,只能实现满足即执行,而不能达到分支效果 <c:if test="${1<2} c:choose可以实现多重分支,类似于if else if判断属性写在test里 <c:choose> <c:when test="${1<2}">true</c:when> <c:when test="${1<2}">false</c:when> <c:otherwise>123</c:otherwise> </c:choose> 动态包含,url属性是资源路径,可以拼接参数 <c:import url="index.jsp?msg=12"></c:import>
C;forEach循环语句
<c:forEach items="${requestScope.list}" var="emp">
</c:forEach>