Java学习十三,web进阶(JSTL,EL,AJAX,过滤器,监听器)

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常用标签及案例

  1. 通用标签
    在这里插入图片描述

    <%--
      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>
    
    
  2. 条件标签

    <%--
      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>
    
  3. 迭代标签

    控制器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个,他们分别是:

监听器的作用域包含接口说明
ServletContextListenercontextInitialized(ServletContextEvent sce);
contextDestroyed(ServletContextEvent sce);
Context容器初始化时触发,在所有的Filter和Servlet的init方法调用之前contextInitialized接口先被调用;
Context容器销毁,在所有的Filter和Servlet的destroy方法调用之后contextDestroyed接口被调用;
HttpSesisonListenerSessionCreated(HttpSessionEvent se);
SessionDestroyed(HtppSessionEvent se);
当一个session对象被创建时触发;
当一个session对象被失效时触发;
ServletRequestListenerrequestInitialized(ServletRequestEvent sre);
requestDestroyed(ServletRequestEvent sre);
当HttpServletRequest对象被传递到用户的Servlet的service方法之前该方法被触发;
当HttpServletRequest对象在调用完用户的Servlet的service方法之后该方法被触发;

其中监听三个域对象中属性的增,删,改的事件监听器分别为:

Listener类含有的接口接口说明
ServletContextAttributeListenerAttributeAdded(ServletContextAttributeEvent scab);
AttributeRemoved(ServletContextAttributeEvent scab);
AttributeReplaced(ServletContextAttributeEvent scab);
当调用servletContext.setAttribute方法时触发这个方法;
当调用servletContext.removeAttribute方法时触发这个方法;
如果在调用servletContext.setAttribute之前该attribute已经存在,则替换这个attribute时,这个方法被触发
HttpSessionAttributeListenerattributeAdded(HttpSessionBindingEvent se);
attributeRemoved(HttpSessionBindingEvent se);
attributeReplaced(HttpSessionBindingEvent se);
session.setAttribute方法被调用时该方法被触发;
session.removeAttribute方法被调用时该方法被触发;
如果在调用session.setAttribute之前该attribute已经存在,则替换这个attribute时这个方法被触发;
ServletRequestAttributeListenerAttributeAdded(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());
    }
}

自次,我们就实现了用户的单点登陆功能.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值