Javaweb-MVC三层架构、Filter、监听器、JDBC

一、什么是MVC

  • model:模型
  • view:视图——>JSP(展示数据、提供一些可以供我们操作的请求
  • Controller:控制器——>servlet(接收用户的请求、响应给客户端内容、重定向或者转发)

以前的架构图:
Javaweb-MVC三层架构、Filter、监听器、JDBC_第1张图片
用户直接访问控制层,控制层就可以直接访问操作数据库;

  • servlet–CRUD–数据库
  • 弊端:程序十分臃肿,不利于维护
  • servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
  • 架构:没有什么是加一层解决不了的!!!!!(如:JDBC,可以连接不同数据库)

MVC三层架构:
Javaweb-MVC三层架构、Filter、监听器、JDBC_第2张图片

  • Model
    • 业务处理:业务逻辑(service)
    • 数据持久层:CRUD(Dao)
  • View
    • 展示数据
    • 提供链接发起servlet请求(a、from、img····)
  • Controller
    • 接收用户的请求:request(请求参数、Session信息···)
    • 交给业务层处理对应的代码
    • 控制视图的跳转
      • 登录---->接收用户的登录请求---->处理用户请求(获取用户登录的参数:username、password····)------>交给业务层处理登录的参数(判断用户名密码是否正确:事务)---->Dao层查询用户名和密码是否正确—>数据库

二、Filter过滤器

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

  • 处理中文乱码
  • 登录验证····

Javaweb-MVC三层架构、Filter、监听器、JDBC_第3张图片

1、编写过滤器

1、导包
Javaweb-MVC三层架构、Filter、监听器、JDBC_第4张图片
2、实现Filter接口

package com.jjl.filter;
import javax.servlet.*;
import java.io.IOException;

public class CharacterEncodingFilter implements Filter {
   //初始化,web服务器启动时,就已经初始了
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter已经初始化");
    }

    /*
    1、过滤中的所有代码,子啊过期特定的请求的时候都会执行
    2、必须要让过滤器继续执行
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        System.out.println("CharacterEncodingFilter执行前··········");
        chain.doFilter(request,response);//让我们的请求继续走,如果不写,我们程序到这就停止了
        System.out.println("CharacterEncodingFilter执行后··········");
    }

    //销毁,web服务器关闭时过滤器销毁
    @Override
    public void destroy() {
        System.out.println("CharacterEncodingFilter已经销毁");
    }
}

2、web.xml中添加过滤器(filter)

    <filter>
        <filter-name>CharacterEncodingFilterfilter-name>
        <filter-class>com.jjl.filter.CharacterEncodingFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilterfilter-name>

        <url-pattern>/servlet/*url-pattern>
        

    filter-mapping>

三、监听器

实现一个监听器的接口:
编写一个监听器:

package com.jjl.listener;

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

//统计网站在线人数:统计session
public class OnlineCountListener implements HttpSessionListener {
    //创建session监听
    //一旦创建session就会触发事件
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        System.out.println(se.getSession().getId());
        Integer onlineCount=(Integer) context.getAttribute("OnlineCount");
        if (onlineCount==null){
            onlineCount=new Integer(1);
        }else {
            int count= onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }
        context.setAttribute("OnlineCount",onlineCount);
    }

    //销毁session监听
    //一旦session销毁就会触发事件
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
        if (onlineCount == null) {
            onlineCount = new Integer(0);
        } else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count - 1);
        }
        context.setAttribute("OnlineCount", onlineCount);
    }
}

web.xml中注册监听器

    
    <listener>
        <listener-class>com.jjl.listener.OnlineCountListenerlistener-class>
    listener>

JSP获取

<h1>当前有<span style="color: aqua"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%>span>在线h1>

四、过滤器和监听器的常见应用(登录验证)

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

用户登录之后才能进入主页,用户注销之后就不能进入主页了!

  • 1、用户登录之后,向用的session中放入用户的数据
    创建存放用户session的常量
    package com.jjl.util;
    
    public class Constant {
        //提前常量,用于代码中需要经常使用的值
        public final static String USER_SESSION = "USER_SESSION";
    }
    
    验证用户名,如果用户名为admin,则登录成功,并获取session,并跳转到首页,否则登录失败,跳转到错误页面
    package com.jjl.servlet;
    
    import com.jjl.util.Constant;
    
    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")){//登录成功
                req.getSession().setAttribute(Constant.USER_SESSION,req.getSession().getId());//获取session,并向session存放数据(session的id)
                resp.sendRedirect("/sys/success.jsp");
            }else {//登录失败
                resp.sendRedirect("/error.jsp");
            }
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 2、登录成功进入主页后,如果点击注销,则就移除session,并跳转到登录页面,如果没有session也跳转到登录页
    package com.jjl.servlet;
    
    import com.jjl.util.Constant;
    
    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 {
            Object userSession = req.getSession().getAttribute(Constant.USER_SESSION);
            if (userSession!=null){
                req.getSession().removeAttribute(Constant.USER_SESSION);
                resp.sendRedirect("/Login.jsp");
            } else {
                resp.sendRedirect("/Login.jsp");
            }
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 3、添加过滤器,如果直接访问主页,要判断用户有没有登录(有没有获取session),如果用户的session为空,当直接访问主页时就直接跳转到错误页面。
    package com.jjl.filter;
    import com.jjl.util.Constant;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class SysFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //ServletRequest  HttpServletRequest
            HttpServletRequest request1 = (HttpServletRequest) request;
            HttpServletResponse response1 = (HttpServletResponse) response;
    //        Object userSession = request1.getSession().getAttribute("USER_SESSION");
            if(request1.getSession().getAttribute(Constant.USER_SESSION)==null){
                response1.sendRedirect("/error.jsp");
            }
            chain.doFilter(request,response);
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
    
  • 4、web.xml注册
        <servlet>
            <servlet-name>LoginServletservlet-name>
            <servlet-class>com.jjl.servlet.LoginServletservlet-class>
        servlet>
        <servlet-mapping>
            <servlet-name>LoginServletservlet-name>
            <url-pattern>/servlet/loginurl-pattern>
        servlet-mapping>
        <servlet>
            <servlet-name>LogoutServletservlet-name>
            <servlet-class>com.jjl.servlet.LogoutServletservlet-class>
        servlet>
        <servlet-mapping>
            <servlet-name>LogoutServletservlet-name>
            <url-pattern>/servlet/logouturl-pattern>
        servlet-mapping>
        <filter>
            <filter-name>SysFilterfilter-name>
            <filter-class>com.jjl.filter.SysFilterfilter-class>
        filter>
        <filter-mapping>
            <filter-name>SysFilterfilter-name>
            <url-pattern>/sys/*url-pattern>
        filter-mapping>
    
  • 5、前端JSP页面
    登录页
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <form action="/servlet/login" method="post">
        用户名:<input type="text" name="username"><br>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>
    
    主页:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>主页</title>
    </head>
    <body>
    <h1>主页</h1>
    <p><a href="/servlet/logout">注销</a></p>
    </body>
    </html>
    
    错误页:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录失败</title>
    </head>
    <body>
    <h1>用户名错误</h1>
    <a href="/Login.jsp">返回登录页</a>
    </body>
    </html>
    

五、JDBC

什么是JDBC:Java连接数据库
需要jar的支持

  • mysql-connector-java

1、连接数据库并查询数据

package com.jjl.test;
import java.sql.*;
public class TestJdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=ut8&useSSL=true";
        String username="root";
        String password="1234qwer";
        //加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection= DriverManager.getConnection(url,username,password);
        //向数据库发送sql的对象,CRUD
        Statement statement = connection.createStatement();
        //编写sql
        String sql = "SELECT * FROM users;";
        //查询sql
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("password"));
            System.out.println("email"+resultSet.getObject("email"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
        }
        //关闭数据库连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

2、PreparedStatement对象——防止sql注入

package com.jjl.test;

import java.sql.*;
import java.util.Date;

public class TestJdbc2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=ut8&useSSL=true";
        String username="root";
        String password="1234qwer";

        //加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        Connection connection= DriverManager.getConnection(url,username,password);

        //使用? 占位符代替参数
        String sql =  "INSERT into users(id,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);//预编译sql,先写sql,然后不执行
//手动给参数赋值
        preparedStatement.setInt(1,6);
        preparedStatement.setString(2,"zhangba");
        preparedStatement.setString(3,"1234");
        preparedStatement.setString(4,"[email protected]");
        //注意点:sql.Date是数据库的
        // util.Date Java new Date().getTime() 获得时间戳
        preparedStatement.setDate(5,new java.sql.Date(new Date().getTime()));

        //执行sql
        int i = preparedStatement.executeUpdate();
        if(i>0){
            System.out.println("成功插入:"+i+"行");
        }
    }
}

4、用junit单元测试

不用main方法也能测试代码块
导入依赖

<dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.11version>
        <scope>testscope>
    dependency>

简单使用
@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行

5、事务

https://blog.csdn.net/qq_43427354/article/details/125387204

你可能感兴趣的:(学习笔记,mvc,架构,servlet)