实现用户登录
注:本人有关java博客皆根据b站博主狂神说所写,但是在我没有跟随他学习之前朋友已经把他做好的狂神的项目发给我了,所以这里我就不使用狂神的项目来实现,我会使用我之前实训课程的项目来实现,但是基本代码还是和狂神学习的,只是静态资源和数据库使用的是实践时的资源,(就是因为有了这次实训经历,才发现自己所学习的东西根本就不系统,所以才重新学习)如果需要狂神的项目另辟蹊径,同时我会把我这个项目的静态资源上传供大家免费下载,数据库也会上传,所以下面就不展示数据库表的内容了
资源下载
阿里云盘
百度网盘:提取码:qbmv
准备工作
首先搭建好环境,创建一个新的项目,导入需要的jar包
这里是我导入的有关依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jsp-api</artifactId>
<version>6.0.14</version>
</dependency>
<!-- JSTL表达式的依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
处理错误页面和字符编码问题的过滤器
package com.wx.filter;
import com.wx.entity.User;
import com.wx.util.Constants;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//处理非法访问
public class SysFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException{
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
//System.out.println("SysFilter doFilter()===========");
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
//过滤器,从session中获取用户
User user = (User)request.getSession().getAttribute(Constants.USER_SESSION);
//User user = (User)request.getSession().getAttribute("userSession");
if(user == null){//已经被移除或者注销了,或者未登录
response.sendRedirect("error.jsp");
//System.out.println("未登录");
}else {
chain.doFilter(req, resp);
//System.out.println("过滤器");
}
}
public void destroy() {
}
}
package com.wx.filter;
import javax.servlet.*;
import java.io.IOException;
//处理字符编码问题
public class CharacterEncodingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
//@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");
response.setContentType("text/css,charset=utf-8");
chain.doFilter(request, response);
}
//@Override
public void destroy() {
}
}
在web.xml中的注册
<!--非法访问过滤器-->
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.wx.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/view/*</url-pattern>
</filter-mapping>
<!-- 字符编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>com.wx.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后导入静态资源开始编写项目
首先来看一下我已经写好的项目目录
下面是代码展示
数据库公共类
package com.wx.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCon {
private static String driver;
private static String url;
private static String username;
private static String password;
//静态代码块,加载就初始化
static {
Properties properties = new Properties();
//读取db.properties内容
InputStream is = JDBCon.class.getClassLoader().getResourceAsStream("db.properties");
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=properties.getProperty("driver");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
}
public static Connection getConnection() throws ClassNotFoundException, SQLException {
//获取数据库的链接
Connection connection=null;
Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
return connection;
}
//查询公共类
public static ResultSet execute(Connection connection,PreparedStatement preparedStatement, ResultSet rs ,String sql,Object[] params) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i <params.length ; i++) {
//Object不能从0开始,数组要从0开始
preparedStatement.setObject(i+1,params[i]);
}
/*
for (int i = 1; i <params.length ; i++) {
//Object不能从0开始,数组要从0开始
preparedStatement.setObject(i,params[i-1]);
这样写会报:No value specified for parameter 1
没有为参数1指定值
}
*/
rs = preparedStatement.executeQuery();
return rs;
}
//增删改出公共方法
public static int execute(Connection connection, PreparedStatement preparedStatement,String sql, Object[] params) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i <params.length ; i++) {
//Object不能从0开始,数组要从0开始
preparedStatement.setObject(i+1,params[i]);
}
int updateRows = preparedStatement.executeUpdate();
return updateRows;
}
//释放资源
public static boolean close(Connection connection, PreparedStatement preparedStatement, ResultSet rs) throws SQLException {
boolean flag=true;
if (rs!=null){
rs.close();
//GC回收
rs=null;
}else {
flag=false;
}
if (connection!=null){
connection.close();
//GC回收
connection=null;
}else {
flag=false;
}
if (preparedStatement!=null){
preparedStatement.close();
//GC回收
preparedStatement=null;
}else {
flag=false;
}
return flag;
}
}
实体类User
package com.wx.entity;
public class User {
private int id;
private String username;
private String password;
private String name;
private int age;
private String tel;
private int status;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername(String u_username) {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
UserDao
package com.wx.dao.user;
import com.wx.entity.User;
import java.sql.Connection;
public interface UserDao {
public User getLoginUser(Connection connection, String username);
}
UserDaoImpl
package com.wx.dao.user.impl;
import com.wx.dao.JDBCon;
import com.wx.dao.user.UserDao;
import com.wx.entity.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDaoImpl implements UserDao {
@Override
public User getLoginUser(Connection connection, String username) {
PreparedStatement pstm = null;
ResultSet rs = null;
User user = null;
if (connection != null) {
String sql = " select * from user where u_username= ? ";
Object[] params = {
username
};
try {
rs = JDBCon.execute(connection, pstm, rs, sql, params);
if (rs.next()) {
user = new User();
user.setUsername(rs.getString("u_username"));
user.setId(rs.getInt("u_id"));
user.setAge(rs.getInt("u_age"));
user.setPassword(rs.getString("u_password"));
user.setTel(rs.getString("u_tel"));
user.setStatus(rs.getInt("u_status"));
}
JDBCon.close(null,pstm,rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
return user;
}
}
UserService
package com.wx.service.user;
import com.wx.entity.User;
public interface UserService {
public User login(String username , String password);
}
UserServiceImpl
这里在狂神实现用户登录的视频中并没有验证密码,在他的原代码中只需要用户名正确就可以登录成功(因为他在为学生展示新东西应该忘记添加了,因为他提到了没有验证密码,但后续却没有添加),这里我添加了if(user.getPassword().equals(password)){ return user; }
然后将下面的返回值改成由user改成null,实现了验证密码
package com.wx.service.user.impl;
import com.wx.dao.JDBCon;
import com.wx.dao.user.UserDao;
import com.wx.dao.user.impl.UserDaoImpl;
import com.wx.entity.User;
import com.wx.service.user.UserService;
import java.sql.Connection;
import java.sql.SQLException;
public class UserServiceImpl implements UserService {
//业务层都会调用dao层,所以我们要引入Dao层;
private UserDao userDao;
public UserServiceImpl() {
userDao = new UserDaoImpl();
}
@Override
public User login(String username, String password) {
Connection connection = null;
User user = null;
try {
connection = JDBCon.getConnection();
user = userDao.getLoginUser(connection, username);
if(user.getPassword().equals(password)){
return user;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
JDBCon.close(connection,null,null);
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
}
LoginServlet
package com.wx.servlte.user;
import com.wx.entity.User;
import com.wx.service.user.UserService;
import com.wx.service.user.impl.UserServiceImpl;
import com.wx.util.Constants;
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("u_username");
String password = req.getParameter("u_password");
UserService userService = new UserServiceImpl();
User user = userService.login(userName,password);
if(user!=null){
//将用户信息存在session中
req.getSession().setAttribute(Constants.USER_SESSION,user);
//跳到主页
resp.sendRedirect("admin.jsp");
}
else{
req.setAttribute("error","用户名或密码不正确");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
到这里所有的源码就展示完成,下面看看登录效果
登录进来后中间页面是直接将用户表打印出来,因为这个servlet还没有写,所以会显示404
验证是密码错误还是账号错误
在实训中老师也给我们留了个问题,就是当账号密码输入错误时,在页面显示是账号错了,还是密码错了
我当时实现的登录功能是写在了servlet中(这也就是后来为什么我选择重新学的原因),然后再把密码查询出来和用户输入的进行比对,然后再输出到前台页面,写这个博客的时候用到实训资源又想起了那次实训,刚好实训老师为我们展示的代码我也保留了下来
UserDao
boolean findbyusername(String username);
boolean findbyusernameAndpassword(String username, String password);
UserdaoImpl
@Override
public boolean findbyusername(String username) {
String sql="select u_id from user where u_username=?";
Object[] obj={username};
ResultSet rs= DButil.select(sql, obj);
try {
if (rs.next()) {
return true;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
@Override
public boolean findbyusernameAndpassword(String username, String password) {
String sql="select u_id from user where u_username=? and u_password=?";
Object[] obj={username,password};
ResultSet rs= DButil.select(sql, obj);
try {
if (rs.next()) {
return true;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
UserService
int login(String username, String password) ;
UserServiceImpl
@Override
public int login(String username, String password) {
boolean usernamea= userDao.findbyusername(username);
if (usernamea) {
if (userDao.findbyusernameAndpassword(username, password)) {
return 1;
}else {
return 2;
}
}else {
return 3;
}
}
LoginServlet
//设置日志
Logger logger =Logger.getLogger(LoginServlet.class);
String username=request.getParameter("u_username");
String password=request.getParameter("u_password");
UserService userService =new UserServiceImpl();
int i=userService.login(username, password);
if (i==1) {
request.getRequestDispatcher("/admin.jsp").forward(request, response);
}else if (i==2) {
request.setAttribute("error", "密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}else {
request.setAttribute("error", "账号错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
这样就实现了显示是账号错误还是密码错误,当方法不唯一,相信大家还有别的方法来实现