目录
1.JSTL和EL表达式
1.1 EL表达式的介绍和作用
目的是代替JSP页面中的复杂代码,他的基本语法是: ${变量名}
1.1.1 EL的案例展示
1.1.2 案例实施
创建表单提交页面EL/EL.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL页面</title>
<link rel="stylesheet" href="../css/login.css">
</head>
<body>
<div class="login">
<form action="${pageContext.request.contextPath}/el" method="post">
<table>
<tr>
<td class="td1">用户名</td>
<td><input type="text" class="input1" name="username"></td>
</tr>
<tr>
<td class="td1">年龄</td>
<td><input type="text" class="input1" name="age"></td>
</tr>
<tr>
<td colspan="2">
<div class="btn-red">
<input type="submit" value="登录" id="login-btn">
</div>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
创建控制器el.java
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 java.io.IOException;
@WebServlet("/el")
public class el extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取username和age的属性值
String name = request.getParameter("username");
String age = request.getParameter("age");
// 2.获取的数据保存到request和session域中
request.setAttribute("name", name);
request.setAttribute("age", age);
request.getSession().setAttribute("name","Hello Kitty");
request.getSession().setAttribute("age","11");
// 3.跳转到showEL.jsp页面中
request.getRequestDispatcher("EL/showEL.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
最后创建展示页面EL/showel.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2019/3/12 0012
Time: 09:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>展示</title>
</head>
<body>
姓名:${name}
年龄:${age}
<hr style="height:1px;border:none;border-top:1px solid #555555;" />
姓名:${requestScope.name}
年龄:${requestScope.age}
<hr style="height:1px;border:none;border-top:1px solid #555555;" />
姓名:${sessionScope.name}
年龄:${sessionScope.age}
</body>
</html>
结果如图:
1.2 JSTL介绍
JSTL是jsp的标准标签库,通常会与EL表达式合作实现JSP页面的编码,需要注意的是,在使用JSTL的时候需要在JSP页面添加taglib指令:<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
1.2.1 JSTL常用标签及案例
-
通用标签
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/3/12 0012 Time: 09:54 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>JSTL的标签</title> </head> <body> set,out,remove标签 <br> set标签主要是在指定域中存放数据 <c:set var="name" value="张帅" scope="request"></c:set> <br> out标签打印指定数据: <c:out value="${name}"></c:out> <br> remove标签是删除数据 <c:remove var="name" scope="request"></c:remove> <br> <br> 删除后打印输出: <c:out value="${name}"></c:out> </body> </html>
-
条件标签
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/3/12 0012 Time: 10:17 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <title>JSTL中if标签的使用</title> </head> <body> 设置age的大小 <c:set var="age" value="13" scope="request"></c:set> <br> 使用if标签 <c:if test="${age==12}"> 您的年龄是:12 </c:if> <br> 使用choose标签 <c:choose> <c:when test="${age == 12}"> 您的年龄是:12岁 </c:when> <c:otherwise> 你多大了??? </c:otherwise> </c:choose> </body> </html>
-
迭代标签
控制器foreach.java
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 java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @WebServlet("/foreach") public class foreach extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.存放map1和map2到datalist中 Map<String, Object> data1 = new HashMap<String, Object>(); data1.put("name", "联想笔记本"); data1.put("address", "北京"); data1.put("price", 3999); Map<String, Object> data2 = new HashMap<String, Object>(); data2.put("name", "神舟笔记本"); data2.put("address", "上海"); data2.put("price", 1888); List<Map<String, Object>> datalist = new ArrayList<Map<String, Object>>(); datalist.add(data1); datalist.add(data2); //2. 赋值于request域中 request.setAttribute("data", datalist); //3.在/JSTL/for.jsp中取出 request.getRequestDispatcher("JSTL/for.jsp").forward(request, response); } }
JSTL/for.jsp页面
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/3/12 0012 Time: 10:28 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>JSTL中foreach标签的使用</title> </head> <body> <c:forEach items="${data}" var="map"> 名称:${map.name} 产地:${map.address} 价格:${map.price} <br> </c:forEach> </body> </html>
2.AJAX
基本介绍我就不写了,这边只写实现的方法.
创建ajax_login.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ajax登录页面</title>
<link rel="stylesheet" href="./css/login.css">
</head>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<body>
<div class="login">
<%--<form action="/mvc/ajax_login" method="post">--%>
<table>
<tr>
<td class="td1">用户名</td>
<td><input type="text" class="input1" name="username"></td>
</tr>
<tr>
<td class="td1">密码</td>
<td><input type="password" class="input1" name="password"></td>
</tr>
<tr>
<td class="td1" colspan="2">
<input type="checkbox" name="remember" value="true" checked="checked"> 记住用户名
</td>
</tr>
<tr>
<td colspan="2">
<div class="btn-red">
<input type="submit" value="登录" id="login-btn">
</div>
</td>
</tr>
</table>
<%--</form>--%>
</div>
<script>
$("#login-btn").click(function () {
$.ajax({
url:"ajax_login",
type:"post",
data:{
name:$("input[name=username]").val(),
pwd:$("input[name=password]").val()
},
dataType:"json",
success:function(rel){
if (rel.rel==1){
alert("成功")
}else {
alert("失败")
}
}
});
});
</script>
</body>
</html>
完后创建控制器ajax_login.java
import org.json.JSONObject;
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 java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/ajax_login")
public class ajax_login extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> map = new HashMap<String, String>();
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
if ("111111".equals(name) && "111111".equals(pwd)) {
System.out.println("name=" + name);
System.out.println("pwd=" + pwd);
map.put("rel", "1");
}else {
//登陆失败
map.put("rel", "2");
}
//String转化JSON
JSONObject jsonObject = new JSONObject(map);
response.getOutputStream().write(jsonObject.toString().getBytes("UTF-8"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
JSONObject jsonObject = new JSONObject("{flag:false}");
response.getOutputStream().write(jsonObject.toString().getBytes("utf-8"));
}
}
3.过滤器
3.1 过滤器的概述
实现对web资源请求的拦截,完成特殊的操作,尤其是对请求的预处理
3.1.1 过滤器的工作流程
3.1.2 过滤器的生命周期
3.1.3 过滤器的实现步骤
3.1.4 过滤器链
3.2 过滤器的代码实现
简单的写了两个过滤器,一个是为了页面的转码格式(UTF-8),另一个是用户登陆权限认证
基本使用@WebFilter的注释就可以了,不再需要使用XML配置
package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
/**
* 使用注解标注过滤器
*
* @WebFilter将一个实现了javax.servlet.Filte接口的类定义为过滤器 属性filterName声明过滤器的名称, 可选
* 属性urlPatterns指定要过滤 的URL模式,也可使用属性value来声明.(指定要过滤的URL模式是必选属性)
*/
@WebFilter(
filterName = "chars",
value = {"/logins"},
initParams = {
@WebInitParam(name = "encoding", value = "utf-8")
})
public class chars implements Filter {
private FilterConfig config;
public void destroy() {
System.out.println("过滤器的销毁");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("过滤器的执行执行执行执行");
req.setCharacterEncoding(config.getInitParameter("encoding"));
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
System.out.println("过滤器的创建");
}
}
用户的Auth的过滤器实现
package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "auth", value = "/liuyanban/message.jsp")
public class auth implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//转化http请求
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if (request.getSession().getAttribute("login_name") == null) {
response.sendRedirect(request.getContextPath() + "/liuyanban/login.jsp?is_login=1");
return;
} else {
chain.doFilter(request, response);
return;
}
}
public void init(FilterConfig config) throws ServletException {
}
}
4.监听器
监听器用于监听对象的上的事件发生,在Servlet中监听器主要监听请求对象、会话对象、上下文对象以及监听这些对象的作用域操作。JavaEE为我们提供了一系列的监听器接口,开发时按需实现相应的接口即可。
4.1 监听器的定义
4.2 监听器的分类和创建
4.2.1 基本分类
监听器中实现的接口有3个,他们分别是:
监听器的作用域 | 包含接口 | 说明 |
---|---|---|
ServletContextListener | contextInitialized(ServletContextEvent sce); contextDestroyed(ServletContextEvent sce); | Context容器初始化时触发,在所有的Filter和Servlet的init方法调用之前contextInitialized接口先被调用; Context容器销毁,在所有的Filter和Servlet的destroy方法调用之后contextDestroyed接口被调用; |
HttpSesisonListener | SessionCreated(HttpSessionEvent se); SessionDestroyed(HtppSessionEvent se); | 当一个session对象被创建时触发; 当一个session对象被失效时触发; |
ServletRequestListener | requestInitialized(ServletRequestEvent sre); requestDestroyed(ServletRequestEvent sre); | 当HttpServletRequest对象被传递到用户的Servlet的service方法之前该方法被触发; 当HttpServletRequest对象在调用完用户的Servlet的service方法之后该方法被触发; |
其中监听三个域对象中属性的增,删,改的事件监听器分别为:
Listener类 | 含有的接口 | 接口说明 |
---|---|---|
ServletContextAttributeListener | AttributeAdded(ServletContextAttributeEvent scab); AttributeRemoved(ServletContextAttributeEvent scab); AttributeReplaced(ServletContextAttributeEvent scab); | 当调用servletContext.setAttribute方法时触发这个方法; 当调用servletContext.removeAttribute方法时触发这个方法; 如果在调用servletContext.setAttribute之前该attribute已经存在,则替换这个attribute时,这个方法被触发 |
HttpSessionAttributeListener | attributeAdded(HttpSessionBindingEvent se); attributeRemoved(HttpSessionBindingEvent se); attributeReplaced(HttpSessionBindingEvent se); | session.setAttribute方法被调用时该方法被触发; session.removeAttribute方法被调用时该方法被触发; 如果在调用session.setAttribute之前该attribute已经存在,则替换这个attribute时这个方法被触发; |
ServletRequestAttributeListener | AttributeAdded(ServletRequestAttributeEvent srae); AttributeRemoved(ServletRequestAttributeEvent srae); AttributeReplaced(ServletRequestAttributeEvent srae); | 当调用request.setAttribute方法时触发这个方法; 当调用request.removeAttribute方法时触发这个方法; 如果在调用request.setAttribute之前该attribute已经存在,则替换attribute时这个方法被触发; |
4.2.2 ServletContextListener
package listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener()
public class mycontext implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("app_name","测试");
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
4.2.3 HttpSesisonListener
package listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.Date;
@WebListener()
public class mysession implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
String name = (String) se.getSession().getAttribute("login_name");
String sessionid = se.getSession().getId();
Date createtime = new Date(se.getSession().getCreationTime());
System.out.println("id::" + sessionid + "时间::" + createtime + "name:" + name);
}
public void sessionDestroyed(HttpSessionEvent se) {
String sessoinid = se.getSession().getId();
System.out.println("sessionid" + sessoinid);
}
}
4.2.4 ServletRequestListener
package listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
@WebListener()
public class requests implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("请求销毁了");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
String path = request.getRequestURI();
String info = request.getParameter("is");
System.out.println("路径是:" + path + "请求的'is'信息是:" + info);
}
}
4.3 案例实践
通过HttpSessionAttributeListener类来监听session的创建,从而实现用户的单点登陆,基本的思想是生成新的session 通过唯一标识(这里是用户名)判断是否在在线用户的map中,在的话重新剔除旧的即可;
先创建单例模式的user_session.java
package model;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
public class user_session {
private static user_session Instance = new user_session();
public static user_session get_user_session() {
return Instance;
}
private Map<String, HttpSession> map = new HashMap<String, HttpSession>();
public HttpSession mapget(String name) {
return map.get(name);
}
public void mapput(String name, HttpSession value) {
map.put(name, value);
}
public String toString() {
return map.toString();
}
public void mapremove(String name) {
map.remove(name);
}
}
其次创建监听器httpsession.java
package listener;
import model.user_session;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener()
public class httpsession implements HttpSessionAttributeListener {
private final static String user = "login_user";
public void attributeAdded(HttpSessionBindingEvent sbe) {
//1.session是用户登陆的时候
if (this.user.equals(sbe.getName())) {
//2.判断是否在session的map中
if (user_session.get_user_session().mapget((String) sbe.getValue()) == null) {
System.out.println("没有赋值");
HttpSession session = sbe.getSession();
user_session.get_user_session().mapput((String) sbe.getValue(), session);
} else {
//存在的话销毁login_user的session
user_session.get_user_session().mapget((String) sbe.getValue()).invalidate();
user_session.get_user_session().mapremove((String) sbe.getValue());
}
System.out.println("11111111"+user_session.get_user_session().toString());
//3.更新user_session.get_user_session().mapsbe.getSession().setAttribute("user_session.get_user_session().map,user_session.get_user_session().map;
}
if ("map".equals(sbe.getName())){
System.out.println( sbe.getSession().getAttribute("map").toString());
}
}
public void attributeRemoved(HttpSessionBindingEvent sbe) {
}
public void attributeReplaced(HttpSessionBindingEvent sbe) {
System.out.println("新+++的"+sbe.getName());
}
}
自次,我们就实现了用户的单点登陆功能.