Eclipseは、フレームワークなしでTomcatを統合し、ネイティブサーブレットとjdbcをそれ自体でカプセル化して、小さなWebプロジェクトを実現します。

導入する

実際、これは、B / Sアーキテクチャスタイルを体験するためのソフトウェアアーキテクチャのコースの実験作業から来ています。元の実験では、簡単な登録およびログイン機能を実装する必要があります。ただし、学校のカリキュラムシステム構造は非常に魅力的です。phpやjava webなどの技術コースはすべて選択科目であり、今学期のjavawebコースはサーブレットをスキップしてSSMを直接教えます。

そのため、実験クラスの教師がphpとjavaのコードを提供しましたが、コードは比較的単純で、関数の拡張は考慮されていません。私はまだそれを自分で書くことを選びます。

TomcatをEclipseEEに統合し、ネイティブサーブレットとjdbcをカプセル化し、ログインデモを実現します。同時に、このようなカプセル化は、Javaフレームワークなしで小さなWebプロジェクトの実現をサポートできます。

エフェクト画像

TomcatをEclipseEEに統合する

1.サーバーを追加します

2.サーブレットに関連するjarパッケージを追加します

Tomcatは、サーブレットとjspをサポートするJavaで記述されたWebアプリケーションサーバーです。サーブレットとjspに関連するjarパッケージはjdkに組み込まれていませんが、Tomcatのクラスライブラリ(インストールディレクトリの下のlibディレクトリ)から取得されます。新しく作成したWebプロジェクトにtomcatランタイムクラスライブラリを追加する必要があります。そうしないと、プロジェクトでサーブレットとjspを使用する方法がありません。

   

   

3.ポート番号とコンテキストパスを設定します

   

Daoレイヤーはjdbcをカプセル化して、データベース操作を簡素化します

1.対応するバージョンのドライバーjarパッケージをインポートします

2.データベース接続用のカスタム構成ファイルを作成します

JDBC.properties

# 中心仓库:https://mvnrepository.com/

# mysql驱动jar包
# 8.0.16:https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.16
# 5.1.47:https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.47

# 数据库连接的基本配置
user=root
password=ysqJYKL2010
# 不设置useSSL会有警告
url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=true
driver=com.mysql.jdbc.Driver

3.データベース接続を取得するためのクラスを作成します

DbConnector.java

package dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import utils.CloseUtil;

/**
 * 数据库连接类 初始化数据库连接配置,获取数据库连接
 * 
 * @author passerbyYSQ
 * @date 2020-9-29 14:19:37
 */
public class DbConnector {

	/**
	 * 连接数据库的基本配置,从配置文件读入。
	 */
	private static String user;
	private static String password;
	// 数据库连接协议的url
	private static String url;
	// 数据库驱动包的类路径
	private static String driver;

	// 存储配置文件的数据结构Properties
	private static Properties configProp = new Properties();

	static {
		InputStream inputStream = null;
		try {
			ClassLoader classLoader = DbConnector.class.getClassLoader();
			// 在src目录下获取JDBC.properties的输入流
			inputStream = classLoader.getResourceAsStream("JDBC.properties");

			if (inputStream == null) {
				throw new RuntimeException("配置文件不存在");
			}

			// 将配置文件加载到configProp
			configProp.load(inputStream);

			user = configProp.getProperty("user");
			password = configProp.getProperty("password");
			url = configProp.getProperty("url");
			driver = configProp.getProperty("driver");

			// 注册数据库驱动包
			Class.forName(driver);
//			System.out.println("注册数据库驱动包成功!");

		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			CloseUtil.close(inputStream);
		}
	}

	/**
	 * 获取一个数据库连接对象
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		try {
			return DriverManager.getConnection(url, user, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 释放资源
	 * 
	 * @param stmt 执行sql语句的对象
	 * @param conn 数据库连接对象
	 */
	public static void close(Statement stmt, Connection conn) {
		close(null, stmt, conn);
	}

	/**
	 * 释放资源的重载形式
	 * 
	 * @param rs   结果集对象
	 * @param stmt 执行sql语句的对象
	 * @param conn 数据库连接对象
	 */
	public static void close(ResultSet rs, Statement stmt, Connection conn) {
		try {
			if (rs != null) {
				rs.close();
			}
			if (stmt != null) {
				stmt.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

4.基本的なデータベース操作ツールを作成します

DaoUtil.java

package dao;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Date;
 
/**
 * 基础的数据库操作工具类
 * 简化通用的基础的增删改查的操作,与具体业务逻辑无关
 * 
 * @author	passerbyYSQ
 * @date	2020-9-29 14:51:16
 */
public class DaoUtil {
	/**
	 * 通用的查询操作
	 * 
	 * @param <T>	查询返回的数据,基类中无法确定,需要通过泛型抛给子类
	 * @param sql	sql语句(里面有占位符)
	 * @param pack	一个接口,该接口有个抽象方法将ResultSet回调给子类,让子类来处理ResultSet中数据
	 * @param args	与占位符一一对应的参数值
	 * @return		封装后的查询结果
	 */
	public static <T> T select(String sql, PackResult<T> pack, Object... args) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet resultSet = null;
		T result = null;
		try {
			conn = DbConnector.getConnection();
			pstmt = conn.prepareStatement(sql);
			
			// 将参数设置到sql语句的占位符中
			setValue(pstmt, args);
			
			resultSet = pstmt.executeQuery();
 
			// 由于不同的表对应不同的实体类,在基类中无法实现将resultSet封装成对应的实体类返回
			// 故只能通过接口中的回调函数交给子类去实现
			result = pack.onResultReturn(resultSet);
			return result;
 
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			DbConnector.close(resultSet, pstmt, conn);
		}
	}
	
	/**
	 * 获取结果集数量
	 * @param from	from部分,传递时不需要带"from"。之所以传递from部分,而不是表名,是考虑到多表查询
	 * @param where	where部分,传递时不需要带"where",里面含有占位符
	 * @param args	代替占位符的参数值
	 * @return		记录数
	 */
	public static int getCount(String from, String where, Object... args) {
		String sql = "select count(*) from " + from + " where " + where;
 
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet resultSet = null;
		try {
			conn = DbConnector.getConnection();
			pstmt = conn.prepareStatement(sql);
			
			// 将参数设置到sql语句的占位符中
			setValue(pstmt, args);
			
			resultSet = pstmt.executeQuery();
			// 获取失败返回-1
			return resultSet.next() ? resultSet.getInt(1) : -1;
 
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		} finally {
			DbConnector.close(resultSet, pstmt, conn);
		}
 
	}
	
	/**
	 *  插入记录,比较适用于插入一条或几条数据。不适合插入一个集合的数据
	 * @param sql	sql语句(里面有占位符)
	 * @param args	与占位符一一对应的参数值
	 * @return		受影响的行数
	 */
	public static int insertOrUpdateOrDelete(String sql, Object... args) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		int count = 0;
		try {
			conn = DbConnector.getConnection();
			pstmt = conn.prepareStatement(sql);
			
			// 将参数设置到sql语句的占位符中
			setValue(pstmt, args);
			//System.out.println(pstmt.toString());
			
			// 受影响的行数
			count = pstmt.executeUpdate();
			return count;
			
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		} finally {
			DbConnector.close(pstmt, conn);
		}
	}
	
	/**
	 * 事务操作
	 * 如果实现类不使用回调的PreparedStatement和ResultSet的引用,
	 * 而是选择自己new新的实例,那么就需要自己负责资源关闭
	 * 
	 * @param sqlEntitys	
	 */
	public static void updateInTransaction(MoreUpdate moreUpdate) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = DbConnector.getConnection();
			conn.setAutoCommit(false); // 开启事务(手动提交)
			
			moreUpdate.updateActions(conn, pstmt, rs);
			
			conn.commit(); // 提交事务
			
		} catch (SQLException e) {
			e.printStackTrace();
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		} finally {
			DbConnector.close(rs, pstmt, conn);
		}
	}
	
	/**
	 * 插入一条记录。如果主键是自增长的,返回该条记录的id
	 * 注意:主键必须是自增长的!!!
	 * @param sql
	 * @param args
	 * @return
	 */
	public static int insertReturnId(String sql, Object... args) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = DbConnector.getConnection();
			pstmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
 
			// 将参数设置到sql语句的占位符中
			setValue(pstmt, args);
			//System.out.println(pstmt.toString());
 
			pstmt.executeUpdate();
			// 获取最后插入的记录的自增长id。修改是不会返回的
			rs = pstmt.getGeneratedKeys();
 
			return rs.next() ? rs.getInt(1) : 0;
 
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		} finally {
			DbConnector.close(rs, pstmt, conn);
		}
	}
 
 
	// 将参数设置到sql语句的占位符中
	public static void setValue(PreparedStatement pstmt, Object... args) throws SQLException {
		for (int i = 0; i < args.length; i++) {	
			if (args[i] instanceof String) { // 主要
				pstmt.setString(i + 1, (String) args[i]);
			} else  if (args[i] instanceof Integer) { // 主要
				int num = (Integer) args[i];
				pstmt.setInt(i + 1, num);
			} else  if (args[i] instanceof LocalDateTime) { // 主要
				pstmt.setTimestamp(i + 1, Timestamp.valueOf((LocalDateTime) args[i]));
			} else if (args[i] instanceof Date) { // 主要 ((Date) args[i]).getTime()
				pstmt.setTimestamp(i + 1, new Timestamp(((Date) args[i]).getTime()));
			} else if (args[i] instanceof BigDecimal) {
				pstmt.setBigDecimal(i + 1, (BigDecimal) args[i]);
			} else if (args[i] instanceof Double) {
				pstmt.setDouble(i + 1, (Double) args[i]);
			} else if (args[i] instanceof Float) {
				pstmt.setFloat(i + 1, (Float) args[i]);
			} else if (args[i] instanceof Boolean) {
				pstmt.setBoolean(i + 1, (boolean) args[i]);
			} else {
				throw new RuntimeException("DaoUtil类暂不支持set该数据类型");
			}
		}
	}
	
	public interface PackResult<T> {
		// 将ResultSet回调给子类,让调用者来处理ResultSet中的数据(转换成特定的pojo)
        T onResultReturn(ResultSet rs) throws Exception; 
	}
	
	public interface MoreUpdate {
		/**
		 * 多种update相关的操作
		 * 
		 * 如果实现类不使用回调的pstmt,而是选择自己new新的pstmt,那么
		 * 就需要自己负责pstmt的关闭操作。
		 * 
		 * @param conn
		 * @param pstmt		回调给实现类的是null
		 * @throws SQLException 
		 */
		void updateActions(Connection conn, PreparedStatement pstmt, ResultSet rs) throws SQLException;
	}
	
}

5.データベーステーブルに対応するエンティティクラスを記述します

Userエンティティクラスに対応するtb_userテーブルは1つだけです。

User.java

package entity;

import java.time.LocalDateTime;

/**
 * 用户实体类
 * 数据库表所对应的实体类
 * 
 * @author	passerbyYSQ
 * @date	2020-9-30 20:46:28
 */
public class User {
	
	private Integer userId;
	
	private String username;
	
	private String password;
	
	// 最后一次登录的时间
	private LocalDateTime lastLoginTime;
	
	public User(Integer userId, String username) {
		this.userId = userId;
		this.username = username;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public LocalDateTime getLastLoginTime() {
		return lastLoginTime;
	}

	public void setLastLoginTime(LocalDateTime lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}
}

サーブレットを書く

1.検証コードイメージを生成するサーブレット

VerificationCodeServlet.java

package servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 生成简单的验证码图片
 * 
 * @author	passerbyYSQ
 * @date	2020-9-30 20:24:02
 */
@WebServlet("/verification_code")
public class VerificationCodeServlet extends HttpServlet {
	private static final long serialVersionUID = 2523187418823246381L;
	
	private Integer width = 100;
	private Integer height = 40;
	private Integer charCnt = 4; // 验证码图片中字符的个数
	private Integer lineCnt = 8;

	private Random r = new Random(); // 用于生产随机数

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 创建图片对象
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		Graphics g = image.getGraphics();
				
		// 填充背景色
		g.setColor(getBgColor());
		g.fillRect(0, 0, width, height);

		g.setFont(new Font("黑体", Font.BOLD, 30));
		// 写字符
		StringBuilder sbd = new StringBuilder();
		for (int i = 1; i <= charCnt; i++) {
			g.setColor(getCharColor());
			int x = width / (charCnt + 2) * i;
			int y = height * 2 / 3;
			char c = getRandomChar();
			sbd.append(c);
			g.drawString(c + "", x, y);
		}
		request.getSession().setAttribute("verification_code", sbd.toString());

		for (int i = 1; i < lineCnt; i++) {
			int x1 = r.nextInt(width);
			int y1 = r.nextInt(height);

			int x2 = r.nextInt(width);
			int y2 = r.nextInt(height);

			g.setColor(getLineColor());
			g.drawLine(x1, y1, x2, y2);
		}

		// 输出图片
		ImageIO.write(image, "jpg", response.getOutputStream());
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * 生成一个在区间[low, high]的随机整数
	 * 
	 * @param low
	 * @param high
	 * @return
	 */
	private int getInt(int low, int high) {
		return (low + r.nextInt(high - low + 1));
	}

	/**
	 * 生成一种背景色(相对字符颜色来说较浅)
	 * 
	 * @return
	 */
	private Color getBgColor() {
		int red = getInt(170, 255);
		int green = getInt(170, 255);
		int blue = getInt(170, 255);
		return new Color(red, green, blue);
	}

	/**
	 * 生成一种干扰线的颜色
	 * 
	 * @return
	 */
	private Color getLineColor() {
		int red = getInt(85, 169);
		int green = getInt(85, 169);
		int blue = getInt(85, 169);
		return new Color(red, green, blue);
	}

	/**
	 * 生成一种字符颜色(相对字体颜色较深)
	 * 
	 * @return
	 */
	private Color getCharColor() {
		int red = getInt(0, 84);
		int green = getInt(0, 84);
		int blue = getInt(0, 84);
		return new Color(red, green, blue);
	}

	/**
	 * 生成一个随机字符
	 * 
	 * @return
	 */
	private char getRandomChar() {
		final String chs = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
		return chs.charAt(r.nextInt(chs.length()));
	}

}

2.ログインサーブレット

LoginServlet.java

package servlet;

import java.io.IOException;

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 javax.servlet.http.HttpSession;

import entity.User;
import service.AccountService;
import service.impl.AccountServiceImpl;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1821754212240924673L;
	
	private AccountService accountService = new AccountServiceImpl();

	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		// 获取username
		String username = request.getParameter("username");
		// 获取密码
		String password = request.getParameter("password");
		// 简单的参数判断
		if (username == null || "".equals(username)) {
			request.setAttribute("login_error", "用户名不能为空");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
			return;
		}
		if (password == null || "".equals(password)) {
			request.setAttribute("login_error", "密码不能为空");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
			return;
		}
		
		// 获取用户输入的验证码
		String codeByUser = request.getParameter("verification_code");
		HttpSession session = request.getSession();
		// 取出正确的验证码
		String correctCode = (String) session.getAttribute("verification_code");
		// 验证码是一次性的,取出后失效
		session.removeAttribute("verification_code");
		
		if (codeByUser == null || "".equals(codeByUser)
				|| !codeByUser.equalsIgnoreCase(correctCode)) {
			request.setAttribute("login_error", "验证码错误");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
			return;
		}
		
		User user = accountService.login(username, password);
		if (user == null) {
			request.setAttribute("login_error", "用户名或者密码错误");
			request.getRequestDispatcher("/login.jsp").forward(request, response);
		}
		
		// 登录成功
		session.setAttribute("username", user.getUsername()); 
		response.sendRedirect(request.getContextPath() + "/index.jsp");
	}
}

3.サーブレットからログアウトします

LogoutServlet.java

package servlet;

import java.io.IOException;

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 javax.servlet.http.HttpSession;

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    
	private static final long serialVersionUID = 5967081510030254471L;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String username = (String) session.getAttribute("username");
		
		if (username != null) {
			session.removeAttribute("username");
		}
		response.sendRedirect(request.getContextPath() + "/login.jsp");
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

サービスレイヤーを作成する

AccountServiceImpl.java

package service.impl;

import java.sql.ResultSet;
import java.time.LocalDateTime;

import dao.DaoUtil;
import entity.User;
import service.AccountService;

/**
 * @author	passerbyYSQ
 * @date	2020-9-30 20:50:33
 */
public class AccountServiceImpl implements AccountService {

	@Override
	public User login(String username, String password) {
		String sql = "select * from tb_user where username=? and password=?";
		User user = DaoUtil.select(sql, new DaoUtil.PackResult<User>() {
			@Override
			public User onResultReturn(ResultSet rs) throws Exception {
				if (!rs.next()) {
					return null;
				}
				int userId = rs.getInt("id");
				String username = rs.getString("username");
				// 密码不需要取出
				return new User(userId, username);
			}
		}, username, password);
		
		// 登录成功,更新最后一次登录的时间
		if (user != null) {
			sql = "update tb_user set last_login_time=? where id=?";
			DaoUtil.insertOrUpdateOrDelete(sql, LocalDateTime.now(), user.getUserId());
		}
		
		return user;
	}

}

ログインフィルターを書く

ログインしていないユーザーはホームページにアクセスできず、ログインしているユーザーはログインページにアクセスできません

LoginFilter.java 

package filter;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 拦截器,用于验证是否已经登录
 * 
 * @author	passerbyYSQ
 * @date	2020-10-1 16:28:20
 */
@WebFilter(
		filterName = "loginFilter",
		// 实际上可以把需要拦截的页面分类到某个目录下,某些api也分类,
		// 这样拦截的针对性更强,需要排除的也更少
		urlPatterns = "/*", // 拦截所有url
		initParams = {
			// 不拦截某些页面、api、静态资源
			@WebInitParam(name = LoginFilter.EXECUDED_PAGE, value="login.jsp"),
			@WebInitParam(name = LoginFilter.EXECUDED_API, 
				value="login;logout;verification_code"),
			@WebInitParam(name = LoginFilter.EXECUDED_RESOURCE, 
				value=".jpg;.png;.jpeg;.css;.js"),
			@WebInitParam(name = "encoding", value = "utf-8"), // 编码
		}		
)
public class LoginFilter implements Filter {
	// 页面
	public static final String EXECUDED_PAGE = "EXECUDED_PAGE";
	// API
	public static final String EXECUDED_API = "EXECUDED_API";
	// 静态资源
	public static final String EXECUDED_RESOURCE = "EXECUDED_RESOURCE";
	
	private FilterConfig filterConfig;
	private Set<String> execudedUrl = new HashSet<>();

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		processInitParamArray(EXECUDED_PAGE);
		processInitParamArray(EXECUDED_API);
		processInitParamArray(EXECUDED_RESOURCE);
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
	
		// 设置字符集,防止post表单乱码
		String encoding = filterConfig.getInitParameter("encoding");
		if (encoding == null) {
			encoding = "utf-8";
		}
		httpRequest.setCharacterEncoding(encoding);
		
		// 判断是否需要拦截。默认需要拦截
		boolean isNeedFilter = true;
		String uri = httpRequest.getRequestURI();
		for (String str : execudedUrl) {
			if (uri.endsWith(str)) { // 注意用endsWith
				// 不需要拦截
				isNeedFilter = false;
				break;
			}
		}
		
		HttpSession session = httpRequest.getSession();
		String username = (String) session.getAttribute("username");
		
		// 不需要拦截,放行
		if (!isNeedFilter) {
			if ((uri.endsWith("login") || uri.endsWith("login.jsp")) && username != null) {
				// 已登录,不能访问登录页面
				httpResponse.sendRedirect(httpRequest.getContextPath() + "/index.jsp");
			} else {
				chain.doFilter(httpRequest, httpResponse);
			}
		} else {
			if (username != null) {
				// 已登录,放行
				chain.doFilter(httpRequest, httpResponse);
			} else {
				// 未登录。重定向到登录界面
				httpResponse.sendRedirect(httpRequest.getContextPath() + "/login.jsp");
			}
		}
	}

	@Override
	public void destroy() {
		filterConfig = null;
		execudedUrl.clear();
	}
	
	private void processInitParamArray(String key) {
		String param = filterConfig.getInitParameter(key);
		if (param != null) {
			String[] split = param.split(";");
			for (String str : split) {
				// 静态资源
				if (!"".equals(str)) {
					execudedUrl.add(str);
				}
			}
		}
	}

}

さて、それは終わりました!

フロントページは比較的シンプルなので投稿しません。書くのにそんなに多くを必要とするのは単なるログイン関数ではないかと尋ねる人もいるかもしれません。私たちの焦点は、ネイティブサーブレットとjdbcをカプセル化することであり、これらを拡張して小さなWebプロジェクトの開発をサポートできることに注意してください。ログイン機能をデモとして使用しているだけです。これは、Java Webを勉強したことがあるが、Javaフレームワークに触れたことがない学生にとって非常に参考になります。

おすすめ

転載: blog.csdn.net/qq_43290318/article/details/108904161