DAY 七:
MVC三层架构
MVC: Model View Controller 模型、视图、控制器
早期架构:用户直接访问控制层,控制层可以直接操作数据库
弊端:程序十分臃肿,不利于维护。
后续使用:(除微服务)
Moudle
-
业务处理:业务逻辑(Service)
-
数据持久层:CRUD(Dao)
View -
展示数据
-
提供链接发起Servlet请求(a , form, img…)
Controller -
接收用户的请求:(req:请求参数、Session信息…)
-
交给业务层处理对应的代码
-
控制视图的跳转
例:登录 ---> 接收用户的登录请求 ---> 处理用户的请求(获取用户登录的参数,username,password)--->
交给业务层处理登录业务(判断用户名密码是否正确:事务)---> Dao层查询用户名和密码是否正确 ---> 数据库
Filter过滤器
用来过滤网站的数据:
-
处理中文乱码
-
登录验证
Filter开发步骤: -
导包
-
编写过滤器
(1)导包
(2)实现Filter接口,重写对应的方法
package com.ma.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 已初始化!");
}
@Override
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)
/*
过滤中的所有代码,在过滤特定请求的时候都会执行
必须要让过滤器继续通行
责任链模式【去了解】
*/
filterChain.doFilter(servletRequest,servletResponse); //让我们的请求继续走,如果不写,程序到这里会被拦截停止!
System.out.println("CharacterEncodingFilter执行后......");
}
//销毁:web服务器关闭的时候,过滤会销毁
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter 已销毁!");
}
}
(3)在web.xml中配置Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.ma.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 只要是/servlet的任何请求,都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
监听器
实现监听器接口:(有N种)
package com.ma.listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.xml.bind.Unmarshaller;
public class OnlineCountListener implements HttpSessionListener {
//创建session监听:一旦创建Session就会触发一次这个事件
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext context = httpSessionEvent.getSession().getServletContext();
System.out.println(httpSessionEvent.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 httpSessionEvent) {
final ServletContext context = httpSessionEvent.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);
}
}
Session销毁:
- 手动销毁:
- 自动销毁:在web.xml中配置session过期时间,以分钟为单位
<!-- 配置Session销毁时间-->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
扩展应用: GUI编程中经常使用
import javax.servlet.jsp.tagext.JspFragment;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class TestPanel extends JFrame {
public static void main(String[] args) {
Frame frame = new Frame("HelloWorld");//新建一个窗体
final 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(255,0,0));//设置背景颜色
frame.add(panel);
frame.setVisible(true);
//监听事件,监听关闭事件
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("打开");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("关闭ing");
System.exit(0);//0:正常关闭,1:非正常关闭
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("关闭ed");
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("激活");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("未激活");
}
});
}
}
效果图:也可以实现缩小、放大、关闭
Filter实现权限拦截
用户登录之后才能进入主页,用户注销之后就不能进入主页
<%
Object userSession = request.getSession().getAttribute(“USER_SESSION”);
if (userSession == null) {
response.sendRedirect("/login.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>
登录页面login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<%--在web.xml中注册一个url路径/servlet/loginServlet,其次编写一个该路径的serlvet--%>
<form action="/servlet/loginServlet" 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</title>
</head>
<body>
<h1>错误</h1>
<h3>无登录权限或者用户名错误!</h3>
<a href="/login.jsp" >返回登录页面</a>
</body>
</html>
- 尝试用“admin”登录,一旦登录成功重定向至主页,反之用户名错误,重定向到错误页面error.jap
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("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);
}
}
- 用户登录才能进入主页,用户注销后不能进入主页
(1)用户登录之后,向session中放入用户的数据
(2)进入主页的时候判断用户是否已经登录。在过滤器中实现
import com.ma.util.Constant;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.plaf.PanelUI;
import javax.xml.ws.Response;
import java.io.IOException;
/**
* 实现用户注销后无法登录进入主页,重定向至错误页
**/
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//权限拦截
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest Request = (HttpServletRequest) servletRequest;
HttpServletResponse Response = (HttpServletResponse) servletResponse;
if (Request.getSession().getAttribute(Constant.USER_SESSION) == null) {
Response.sendRedirect("/error.jsp");
}
filterChain.doFilter(Request, Response);
}
@Override
public void destroy() {
}
}
注:另一种做法是:在主页中先做出判断,如果已经注销的话,返回至登录页
<%--【在success.jsp中】只能从主页登录后进入到主页,不可以直接通过url路径进入主页 --%>
<%
Object userSession = request.getSession().getAttribute(Constant.USER_SESSION);
if (userSession == null) {
response.sendRedirect("/login.jsp");
}
%>
DAY 八:
JDBC回顾
1.JDBC编程六部曲
- 加载驱动
- 导入数据库依赖
- IDEA中连接数据库
- 向数据库发送SQL的对象
- 执行查询
- 关闭连接,释放资源
2.预编译
详细内容见其它博客:链接: https://blog.csdn.net/Mj_yong/article/details/116130290.
3.事务
- 开启事务
- 事务提交
- 事务回滚
- 关闭事务