一.前台准备两个jsp页面,一个登录页面,一个登录成功后跳转的页面
1.login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录界面</title>
</head>
<body>
<form action="loginServlet" method="post" id="loginForm">
<div class="col-md-4 col-md-push-4">
<div class="form-group">
<label for="uname">名称</label>
<input type="text" class="form-control" name="uname" id="uname" placeholder="请输入名称" value="${u.uname}">
</div>
<div class="form-group">
<label for="upwd">密码</label>
<input type="password" class="form-control" name="upwd" id="upwd" placeholder="请输入密码" value="${u.upwd}" >
</div>
<button type="button" class="btn btn-default" id="loginBtn">登录</button>
<span style="font-size:12px;color:red" id="msg">${msg}</span>
</div>
</form>
</body>
<script type="text/javascript" src="statics/js/jquery-3.3.0.min.js"></script>
<script type="text/javascript" src="statics/js/login.js"></script>
</html>
2.index.jsp(登录成功后的页面)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>登录首页</title>
</head>
<body>
<h3>欢迎${user.uname }登录使用阿狸云平台</h3>
</body>
</html>
3.为了提高代码复用性,将前台的参数的非空判断写到js文件中,可以直接引入
/**
*
* 前台表单验证的js部分
*
*/
//首先给提交按钮绑定一个点击事件
$("#loginBtn").click(function() {
//获取用户姓名和密码的值
var uname=$("#uname").val();
var upwd=$("#upwd").val();
//对用户填写的姓名和密码进行非空判断
if(uname==null||uname==""){
$("#msg").html("*用户名不能为空");
return;
}
if(upwd==null||upwd==""){
$("#msg").html("*密码不能为空");
return;
}
//如果都不为空,则提交表单
$("#loginForm").submit();
});
二.在WebContent目录下新建statics文件夹,用来存放js,css,image等
注意:需要将mysql的jar包导入lib文件下(需要将mysql打开)
三.接下来准备后台的资源
1.准备properties配置文件
# properties文件默认不支持中文,可通过右键文件,选择" Properties",设置文件的编码为UTF-8
# 等号前后不要有空格
# 驱动名
jdbcName=com.mysql.jdbc.Driver
# 默认用户名 root
dbName=root
# 用户密码 每个人装mysql时密码可能不一样,所以需要修改成自己的
dbPwd=xll123456
# 数据库的链接 "java27"是数据库名
dbUrl=jdbc:mysql://localhost:3306/java27?useUnicode=true&characterEncoding=UTF-8
2.准备获取连接,关闭资源的及后台参数的非空判断
/**
* 数据库工具类
* 1、连接数据库
* 2、关闭资源
* @author Lisa Li
*
*/
public class DBUtil {
public static Connection getConnection(){
Connection connection = null;
try {
// 加载配置文件
InputStream in = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
// 得到配置对象
Properties properties = new Properties();
// 将流对象中的数据加载到配置文件中
properties.load(in);
// 通过properties对象的getProperty()方法得到指定属性的值
String jdbcName = properties.getProperty("jdbcName");
String dbName = properties.getProperty("dbName");
String dbPwd = properties.getProperty("dbPwd");
String dbUrl = properties.getProperty("dbUrl");
// 加载驱动
Class.forName(jdbcName);
// 得到数据库连接
connection = DriverManager.getConnection(dbUrl, dbName, dbPwd);
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
/**
* 关闭资源
* @param resultSet
* @param preparedStatement
* @param connection
*/
public static void close(ResultSet resultSet, PreparedStatement preparedStatement , Connection connection) {
try {
// 判断资源是否为空,不为空则关闭资源
if (resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println(getConnection());
}
}
参数的非空判断:
/**
* 判断参数是否为空
* @param str
* @return
*/
public static boolean isEmpty(String str) {
if (str == null || "".equals(str)) {
return true;
}
return false;
}
}
3.准备一个javaBen
/**
* 用户对象
* @author Lisa Li
*
*/
public class User {
private Integer userId; // 主键,用户ID
private String uname; // 用户名称
private String upwd; // 用户密码
private String remark; // 用户备注
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
4.准备过滤器filter工具类
字符集乱码的解决的工具类
/**
* 字符集乱码解决工具类
*/
@WebFilter("/*")
public class EncodingFilter implements Filter {
public EncodingFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//因为下面的请求request和响应response是HTTPServlet的
//所以这里要进行强转
//基于Http
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)resp;
//设置POST请求的乱码问题(只针对POST,对GET请求无效)
request.setCharacterEncoding("UTF-8");
//获取请求的类型(GET/POST)
String method=request.getMethod();
//判断是否是GET请求
if("GET".equalsIgnoreCase(method)){
//获取服务器版本号
String serverInfo=request.getServletContext().getServerInfo();// Apache Tomcat/8.0.45
//截取字符串得到服务器的版本号(8)
String versionStr=serverInfo.substring(serverInfo.indexOf("/")+1, serverInfo.indexOf("."));
//判断服务器版本是否是7以下的版本
if(versionStr!=null && Integer.parseInt(versionStr)<8){
//进行乱码处理
HttpServletRequest request2=new MyWapper(request);
//放行资源
chain.doFilter(request2, response);
return;
}
}
//放行资源
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
/**
*
* 为了使 处理使用8以下版本服务器的get请求的乱码问题的代码变得灵活,我们就自定一个类来专门处理
* 究其根本的乱码的原因,问题出在request.getParameter()方法;
* 所以我们只要在获取参数的方法这一步解决了get请求的乱码问题就可以了
*
*
* 具体实现步骤:
* 1.定义类,继承HTTPServletRequestWrapper包装类
* 2.重写getParameter方法
* 3.在重写的方法中处理乱码问题
*
*/
class MyWapper extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyWapper(HttpServletRequest request) {
super(request);
this.request=request;
}
//重写getParameter方法
@Override
public String getParameter(String name) {
String value=null;
try {
value=new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return value;
}
}
放行资源的过滤器工具类
/**
* 非法访问拦截
* 当用户未登陆时,访问需要登陆以后才能查看的页面
*
* 1.指定页面,需要放行资源(比如登陆或注册)
* 2.静态资源,放行(比如js,css等等属于statics目录下的)
* 3.指定操作,放行(比如 登陆操作,注册操作,所有不需登就能执行的操作)
*
*/
@WebFilter("/*")
public class LoginAccessFilter implements Filter {
public LoginAccessFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//基于Http
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)resp;
//得到请求的路径
String path=request.getRequestURI();
//指定页面 login.jsp 放行
if(path.contains("/login.jsp")){
chain.doFilter(request, response);
return;
}
//指定资源 静态资源statics ,放行
if(path.contains("/statics")){
chain.doFilter(request, response);
return;
}
//指定操作 登陆操作 loginServlet
if(path.contains("/loginServlet")){
chain.doFilter(request, response);
return;
}
/**
* 用户登录状态才能访问其他资源
* 通过session域对象判断用户是否登录
* 如果用户未登陆,则拦截跳转到登录页面;
* 如果登录,放行到指定资源
*
*/
//获取session域对象中的user对象(用户登陆成功后会将user对象存到session域对象中)
User user=(User)request.getSession().getAttribute("user");
//判断用户是否登录(session域对象中的user对象为空,则表示未登录,不为空,则表示当前是登录状态)
if(user!=null){
//放行
chain.doFilter(request, response);
return;
}
//user为空,则表示未登录,拦截跳转到登录页面
response.sendRedirect("login.jsp");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
5.最后用servlet进行后台操作(参数获取和JDBC操作)
/**
* 用户登录
*/
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 1.获取请求的参数getParameter()
* 2.参数的非空判断
* 如果为空,将错误信息存到request域对象中,请求转发(只在request域对象中有效)到登录页面,并且return
* 3.通过用户名从数据库中查询对象是否存在
* 如果为空,将错误信息存到request域对象中,请求转发(只在request域对象中有效)到登录页面,并且return
* 4.如果用户对象存在,将前台传递来的密码与数据库中查询到的密码作比较
* 如果密码不正确,将错误信息存到request域对象中,请求转发(只在request域对象中有效)到登录页面,并且return
* 5.如果密码正确,则表示登录成功,将用户对象存到session域对象中,且重定向跳转到登录页面index.jsp;
*/
//1.获取请求的参数getParameter()
String uname=request.getParameter("uname");
String upwd=request.getParameter("upwd");
//将前台传递过来的参数设置到request域对象中,前台用来回显
User u= new User();
u.setUname(uname);
u.setUpwd(upwd);
request.setAttribute("u", u);
//2.判断参数是否为空
if(StringUtil.isEmpty(uname)){
//将错误原因存到request作用域
request.setAttribute("msg", "不知道用户名不能为空吗?");
//请求转发到login.jsp
request.getRequestDispatcher("login.jsp").forward(request, response);
return;
}
if(StringUtil.isEmpty(upwd)){
//将错误原因存到request作用域
request.setAttribute("msg", "密码都不知道填吗?");
//请求转发到login.jsp
request.getRequestDispatcher("login.jsp").forward(request, response);
return;
}
//3.通过用户名从数据库中查询对象是否存在(需要jdbc操作,所以封装成方法)
User user=findUserByName(uname);
//判断用户对象是否存在
if(user==null){
//将错误原因存到request作用域
request.setAttribute("msg", "用户不存在");
//请求转发到login.jsp
request.getRequestDispatcher("login.jsp").forward(request, response);
return;
}
//4.用户存在,则比较密码
if(!upwd.equals(user.getUpwd())){
//将错误原因存到request作用域
request.setAttribute("msg", "用户密码不正确");
//请求转发到login.jsp
request.getRequestDispatcher("login.jsp").forward(request, response);
return;
}
//5.如果密码正确,则表示登录成功,将用户对象存到session域对象中,并重定向跳转到index.jsp
request.getSession().setAttribute("user", user);
response.sendRedirect("index.jsp");
}
/**
* JDBC操作从数据库中查询数据
* 1.获取连接
* 2.准备sql语句
* 3.准备预处理块,预编译sql语句(可以占位,防止sql语句注入)
* 4.设置参数,下标从1开始(java操作数据库下标都是从1开始)
* 5.执行查询,返回resultSet结果集
* 6.判断并分析结果集,得到user对象
* 7.关闭资源
* 8.返回user对象
*
*/
public User findUserByName(String uname){
User user=null;
Connection connection=null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
//1.获取连接
connection=DBUtil.getConnection();
//2.准备sql语句
String sql="select * from tb_user where uname=?";
//3.准备预处理块,预编译sql语句
preparedStatement=connection.prepareStatement(sql);
//4.设置参数,下标从1开始
preparedStatement.setString(1, uname);
//5.执行查询语句,返回结果
resultSet=preparedStatement.executeQuery();
//6.判断并分析结果集,得到user对象
while (resultSet.next()) {
user=new User();
//将获取到结果给user对象赋值
user.setRemark(resultSet.getString("remark"));
user.setUname(uname);
user.setUpwd(resultSet.getString("upwd"));
user.setUserId(resultSet.getInt("userId"));
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DBUtil.close(resultSet, preparedStatement, connection);
}
return user;
}
}