JavaWeb(四)
一.MVC三层架构
什么是MVC:Model view Controller
早些年的双层框架
用户直接访问控制层,控制层就可以
servlet–>CRUD–>数据库
弊端:程序十分臃肿,不利于维护
servelt的代码中,处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
经典MVC三层架构
分为:
Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
View
- 展示数据
- 提供链接发起Servlet请求
Controller
- 接收用户的请求:(req:请求参数、Session信息…)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录- ->接收用户登录的请求- ->处理用户登录的请求(获取用户登录的参数,username,password)- ->交给业务层处理登录业务(判断用户名密码是否正确)- ->Dao层查询用户名和密码是否正确
二.Filter过滤器(重点)
用来过滤网站的数据
Filter开发步骤:
- 导包
<?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>org.example</groupId>
<artifactId>javaweb_fillter</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
</project>
- 编写过滤器
import jakarta.servlet.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
/**要过滤的路径*/
@WebFilter(urlPatterns = {"/servlet/*"})
public class CharacterEncodingFilter implements Filter {
/**web服务器启动就会 初始化*/
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("CharacterEncodingFillter初始化");
}
/**web服务器关闭就会 销毁*/
@Override
public void destroy() {
System.out.println("CharacterEncodingFillter销毁");
}
//chain 链
/**过滤器中的所有代码,在过滤特定请求的时候都会执行
* 必须要让过滤器继续通行*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
request.setCharacterEncoding("utf-16");
response.setCharacterEncoding("utf-16");
response.setContentType("text/html;charset=utf-16");
System.out.println("CharacterEncodingFillter执行前");
//让我们的请求继续走,如果不写,程序就会中止
chain.doFilter(request, response);
System.out.println("CharacterEncodingFillter执行后");
}
}
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
/**{"/servlet/show","/showServlet"} 多个地址,使用大括号括起来,方便测试是否通过过滤器*/
@WebServlet(name = "ShowServlet", value = {"/servlet/show","/ShowServlet"})
public class ShowServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("中文乱码测试");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
未通过过滤器页面:
通过过滤器页面:
三.Listener监听器
实现一个监听器的接口;(有N种)
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
/**统计网站在线人数:使用session统计*/
@WebListener
public class OnlineCountListener implements HttpSessionListener{
public OnlineCountListener() {
}
/**session创建监听
* 一旦创建session就会触发一次这个事件*/
public int count=0;
@Override
public void sessionCreated(HttpSessionEvent se) {
count++;
se.getSession().getServletContext().setAttribute("Count", count);
/* Session is created. */
}
/**session销毁监听
* 一旦销毁session就会触发一次这个事件*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
count--;
se.getSession().getServletContext().setAttribute("Count", count);
/* Session is destroyed. */
}
/**session销毁
* 手动销毁
* 自动销毁 服务器关闭销毁*/
}
index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>当前有<span><%=request.getServletContext().getAttribute("Count")%></span>人在线</h1>
</body>
</html>
四.过滤器和监听器的常见应用
监听器:GUI编程中经常使用
用户登录之后才能进入主页,用户注销后就不能进入主页了
- 用户登录之后,向session中放入用户的数据
- 进入主页的时候要判断用户是否已经登录
SysFilter 文件
负责登录检测,有session则可进入主页,否则进入登录页面
import com.mnm.util.Constant;
import jakarta.servlet.*;
import jakarta.servlet.annotation.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = {"/sys/*"})
public class SysFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if (request.getSession().getAttribute(Constant.USER_SESSION)==null) {
response.sendRedirect("/error.jsp");
}
chain.doFilter(req, resp);
}
}
LoginServlet文件
负责创建session
import com.mnm.util.Constant;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "LoginServlet", value = {"/servlet/login","/loginServlet"})
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
if ("admin".equals(username)){
request.getSession().setAttribute(Constant.USER_SESSION,request.getSession().getId());
response.sendRedirect("/sys/success.jsp");
}else {
response.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
LogoutServlet文件
负责退出登录
import com.mnm.util.Constant;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "LogoutServlet", value = {"/LogoutServlet","/servlet/logout"})
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object username = request.getSession().getAttribute(Constant.USER_SESSION);
if (username!=null){
request.getSession().removeAttribute(Constant.USER_SESSION);
response.sendRedirect("/login.jsp");
}else {
response.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
负责存放session名字
public class Constant {
public static String USER_SESSION = "USER_SESSION";
}
success.jsp页面
主页
<%@ 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>
login.jsp页面
负责登录
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>登录</h1>
<form action="/servlet/login" method="post">
<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
error.jsp
错误界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>错误页面</title>
</head>
<body>
<h1>错误:</h1>
<h2>没有权限 或者密码错误</h2>
<p><a href="/login.jsp">返回页面</a> </p>
</body>
</html>
五.扩展:Junit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
简单使用:
@Test注解只在方法上有效,只要加了这个注解的方法,就可以直接使用
import org.junit.jupiter.api.Test;
public class TestJdbc2 {
@Test
public void test(){
System.out.println("测试Junit");
}
}