游客发表

用javaweb做登录网页

发帖时间:2026-10-17 04:56:38

写一个登录页面,用j页JavaWeb项目里最基础也最容易翻车的做登一环。很多人觉得不就是录网个表单提交吗,真动手写的用j页时候,乱码、做登SQL注入、录网session丢失、用j页密码明文存储,做登一个坑接一个坑。录网下面直接拆一个能跑通的用j页登录实现,从数据库建表到Servlet处理,做登代码贴出来,录网坑也标出来。用j页

先建库。做登MySQL里跑一句:

CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT,录网 username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL ); INSERT INTO user (username, password) VALUES ('admin', '123456'); 

注意password字段我故意留了100长度。新手经常写VARCHAR(20),后面想加MD5或者BCrypt存储就直接溢出。这个坑我在三个学生的课程设计里见过,改表结构比改代码烦多了。

前端页面用HTML加一点CSS,别搞太花。login.html:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> <style> body {  font-family: sans-serif; background: #f4f4f4; display: flex; justify-content: center; padding-top: 100px; } .box {  background: #fff; padding: 30px 40px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,.1); } input {  display: block; width: 220px; padding: 8px; margin: 10px 0; border: 1px solid #ccc; border-radius: 4px; } button {  width: 100%; padding: 9px; background: #3a7afe; color: #fff; border: none; border-radius: 4px; cursor: pointer; } </style> </head> <body> <div class="box"> <h3>用户登录</h3> <form action="login" method="post"> <input type="text" name="username" placeholder="用户名" required> <input type="password" name="password" placeholder="密码" required> <button type="submit">登录</button> </form> </div> </body> </html> 

form的method必须写post。用get的话密码直接挂在URL上,浏览器历史、服务器日志全给你记下来,等于裸奔。

后端Servlet。我用JDBC直连,不引框架,方便看清每一步在干什么:

@WebServlet("/login") public class LoginServlet extends HttpServlet {  private static final String URL = "jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf8"; private static final String USER = "root"; private static final String PASS = "yourpassword"; protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); String username = req.getParameter("username"); String password = req.getParameter("password"); try (Connection conn = DriverManager.getConnection(URL, USER, PASS)) {  String sql = "SELECT id, username FROM user WHERE username=? AND password=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs = ps.executeQuery(); if (rs.next()) {  HttpSession session = req.getSession(); session.setAttribute("userId", rs.getInt("id")); session.setAttribute("username", rs.getString("username")); resp.sendRedirect("welcome.jsp"); } else {  resp.getWriter().write("<h3>用户名或密码错误</h3><a href='login.html'>返回</a>"); } } catch (SQLException e) {  e.printStackTrace(); resp.getWriter().write("数据库异常"); } } } 

两个细节值得盯一下。req.setCharacterEncoding("UTF-8")必须放在getParameter之前,放后面等于没写,中文用户名会变问号。另一个是PreparedStatement,别用字符串拼SQL。拼SQL的写法长这样:"WHERE username='" + username + "'",输入admin'-- 就能绕过密码直接登录。这个漏洞每年还在各种作业里出现。

密码存储这块,上面代码是明文比对。实际项目里至少做一次MD5加盐,或者直接用BCrypt。JDBC查出来的密码和用户输入的哈希值比对,数据库里不存原始密码。我见过一个校内论坛的库被拖,两万条明文密码直接暴露,就是因为开发时图省事。

welcome.jsp简单验证一下session:

<%@ page contentType="text/html;charset=UTF-8" %> <% if (session.getAttribute("username") == null) {  response.sendRedirect("login.html"); return; } %> <h2>欢迎,${ username}</h2> <a href="logout">退出</a> 

退出就是session.invalidate(),别只清cookie,服务端的session还在。

整个流程跑通大概半小时。真正花时间的是处理那些边界情况:用户名前后空格、密码长度限制、登录失败次数限制、验证码。这些不在这个最小示例里,但上线前一个都不能少。登录页面看着简单,它是整个系统的门,门不结实,里面装修再好也没用。

    热门排行

    友情链接