JavaWeb(九)——JavaBean、Filter

1. JavaBean

实体类:一般都是和数据库中的表结构一一对应
JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法;

一般用来和数据库的字段做映射 ORM;
ORM :对象关系映射

  • 表—>类
  • 字段–>属性
  • 行记录---->对象
class People{
    private int id;
    private String name;
    private int age;
    private String address;
}

class A{
    new People(1,"美女1号",18"安徽");
    new People(2,"美女2号",27"杭州");
    new People(3,"美女3号",38"西安");
}

JavaBean属性

  • 一个JavaBean对象的属性应该是可访问的。这个属性可以是任意合法的Java数据类型,包括自定义Java类。
  • 一个JavaBean对象的属性可以是可读写,或只读,或只写。 getPropertyName() 和 setPropertyName() 两个方法

进行测试:
建立一个People 类

package com.zz.pojo;

public class People {
    private int id;
    private String name;
    private int age;
    private String address;

    public People() {
    }

    public People(int id, String name, int age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

打开SQLyog软件,创建数据库jdbc,并在数据库下创建表people
在这里插入图片描述
用IDEA连接jdbc数据库
在这里插入图片描述
建立javabean.jsp

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

<jsp:useBean id="people" class="com.zz.pojo.People" scope="page"/>

<jsp:setProperty name="people" property="id" value="1" />
<jsp:setProperty name="people" property="name" value="小胖猪" />
<jsp:setProperty name="people" property="age" value="18" />
<jsp:setProperty name="people" property="address" value="安徽" />


<%--得到--%>
id:<jsp:getProperty name="people" property="id"/>;
姓名:<jsp:getProperty name="people" property="name"/>;
年龄:<jsp:getProperty name="people" property="age"/>;
地址:<jsp:getProperty name="people" property="address"/>

</body>
</html>

测试访问结果:
在这里插入图片描述

2. MVC三层架构

什么是MVC: Model view Controller 模型、视图、控制器

2.1 早些年

在这里插入图片描述
用户直接访问控制层,控制层就可以直接操作数据库;

servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护  
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的!
程序猿调用
|
JDBC
|
Mysql Oracle SqlServer ....

2.2 MVC 三层架构

在这里插入图片描述

Model

  • 业务处理 :业务逻辑(Service)
  • 数据持久层:CRUD (Dao)

View

  • 展示数据
  • 提供链接发起Servlet请求 (a,form,img…)

Controller (Servlet)

  • 接收用户的请求 :(req:请求参数、Session信息….)
  • 交给业务层处理对应的代码
  • 控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确-->数据库

3. Filter (重点)

Filter:过滤器 ,用来过滤网站的数据;

  • 处理中文乱码
  • 登录验证….
    在这里插入图片描述
    Filter开发步骤:
    (1)导包
    在pom.xml文件内进行导包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zz</groupId>
    <artifactId>javaweb-filter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--Servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
        </dependency>

        <!--JSP依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!--JSTL表达式的依赖-->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <!--standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <!--连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

    </dependencies>

</project>

(2)编写过滤器

  • 必须导javax.servlet包

在这里插入图片描述

  • 实现Filter接口,重写对应的方法即可
    CharacterEncodingFilter文件的代码如下:
package com.zz.filter;

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

public class CharacterEncodingFilter implements Filter {

    // 初始化 :web服务器启动,就已经初始化了,随时等待过滤对象出现!
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter初始化");

    }

    //filterChain : 链
    /*
    1. 过滤中的所有代码,在过滤特定请求的时候都会执行
    2. 必须要让过滤器继续同行
       filterChain.doFilter(servletRequest,servletResponse);
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");  //设置编码

        System.out.println("CharacterEncodingFilter执行之前.....");
        filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里就被拦截停止!
        System.out.println("CharacterEncodingFilter执行之后.....");


    }

    //销毁:web服务器关闭的时候,过滤会销毁
    public void destroy() {
        System.out.println("CharacterEncodingFilter销毁");
    }
}

  • ShowServlet文件的代码如下:
package com.zz.servlet;

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

public class ShowServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("你好,小姐姐");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 在web.xml中配置 Filter
<?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>
    <servlet-name>ShowServlet</servlet-name>
    <servlet-class>com.zz.servlet.ShowServlet</servlet-class>
</servlet>

    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/servlet/show</url-pattern>
    </servlet-mapping>


    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/show</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.zz.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--只要是 /servlet的任何请求,会经过这个过滤器-->
        <url-pattern>/servlet/*</url-pattern>
        <!--<url-pattern>/*</url-pattern>-->
    </filter-mapping>
    
</web-app>
  • 测试访问结果:
    访问show 时,没有经过过滤器,会出现乱码问题
    在这里插入图片描述
    访问servlet/show时,经过过滤器,不会出现乱码问题
    在这里插入图片描述
    此时输出控制台显示:
    在这里插入图片描述
    当关闭服务器时,输出控制台显示:
    在这里插入图片描述

4. 监听器

实现一个监听器的接口;(有N种)
(1)编写一个监听器OnlineCountListener
实现监听器的接口HttpSessionListener…

package com.zz.listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {

    //创建session监听: 看你的一举一动
    //一旦创建Session就会触发一次这个事件!
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        System.out.println(se.getSession().getId());

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);

    }

    //销毁session监听
    //一旦销毁Session就会触发一次这个事件!
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);

    }
    
}

(2)web.xml中注册监听器


    <!--注册监听器-->
    <listener>
        <listener-class>com.zz.listener.OnlineCountListener</listener-class>
    </listener>

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

(3)测试访问结果:

在这里插入图片描述

5. 过滤器、监听器的常见应用

监听器应用:GUI编程中经常使用

package com.zz.listener;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("中秋节快乐");  //新建一个窗体
        Panel panel = new Panel(null); //面板
        frame.setLayout(null); //设置窗体的布局

        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(0,0,255)); //设置背景颜色

        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,255,0)); //设置背景颜色

        frame.add(panel);

        frame.setVisible(true);

        //监听事件,监听关闭事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
            }
        });
    }
}

过滤器应用:用户登录之后才能进入登录成功页面(主页)!用户注销后就不能进入登录成功页面了!
(1)用户登录之后,向Sesison中放入用户的数据
(2)进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!

  • 创建的文件有如下:
    在这里插入图片描述
  • 登录页面 Login.jsp 的代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>登录</h1>
<form action="/servlet/login" method="post">
    <input type="text" name="username">
    <input type="submit">
</form>


</body>
</html>

  • 登录成功页面 success.jsp 的代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>欢迎来到主页</h1>
<p><a href="/servlet/logout">注销</a></p>

</body>
</html>
  • 登录错误页面 error.jsp 的代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>错误</h1>
<h3>没有权限,或者用户名错误!</h3>
<a href="/Login.jsp">返回到登录页面</a>

</body>
</html>
  • LoginServlet 的代码如下:
package com.zz.servlet;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取前端请求的参数
        String username = req.getParameter("username");
        //判断
        if(username.equals("admin")){
            //如果登录成功,就把用户信息放到session里面,并且重定向跳转到成功页面
            req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp");
        }else{
            //如果登录失败,就重定向跳转到错误页面
            resp.sendRedirect("/error.jsp");
            
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

  • LogoutServlet 的代码如下:
package com.zz.servlet;

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

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //拿到session
        Object user_session = req.getSession().getAttribute("USER_SESSION");

        //如果session不为空,则移除session,并重定向到登录页面
        if(user_session!=null){
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/Login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 工具包下的常量Constant 的代码如下:
package com.zz.util;

public class Constant {
    public static String USER_SESSION="USER_SESSION";
}

  • 注册页面web.xml 的代码如下:
<?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>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.zz.servlet.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/servlet/login</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.zz.servlet.LogoutServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/servlet/logout</url-pattern>
    </servlet-mapping>
</web-app>
  • 测试访问结果:

    进入登录页面
    在这里插入图片描述
    随意输入,如:2323,就进入了登录错误页面
    在这里插入图片描述
    输入admin, 就进入了登录成功页面,再点击注销按钮
    在这里插入图片描述

  • 发现问题:点击注销后,即未登录成功的情况下,就能直接访问登录成功页面
    在这里插入图片描述
    在这里插入图片描述

  • 解决方法
    方法一(不推荐使用):
    在登录成功的页面上进行限制,即增加下图红方块内代码。
    在这里插入图片描述
    同时在LogoutServlet 中增加如下代码:
    在这里插入图片描述

方法二(推荐使用):
添加一个过滤器,编写SysFilter类,代码如下:

package com.zz.filter;

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

public class SysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //强转成我们常使用的两个对象
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //获取session
        Object user_session = request.getSession().getAttribute("USER_SESSION");
        if(user_session==null){
            //如果session为空,则进入错误页面
            response.sendRedirect("/error.jsp");
        }

        //让过滤器继续往下走
        filterChain.doFilter(request,response);
        
    }

    public void destroy() {

    }
}

在web.xml 中注册过滤器:

  <!--注册过滤器-->
    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.zz.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/sys/*</url-pattern>
    </filter-mapping>

测试访问结果:

进入登录页面
在这里插入图片描述
输入admin,进入登录成功页面后,点击注销按钮
在这里插入图片描述
再输入sys/success.jsp后,不能再进入登录成功页面,显示进入登录错误页面
在这里插入图片描述

发布了62 篇原创文章 · 获赞 2 · 访问量 2726

猜你喜欢

转载自blog.csdn.net/nzzynl95_/article/details/104269272
今日推荐