Spring Mvc 通过拦截器实现登录验证

Java 233次浏览

需求描述:

用户访问需要验证登录的页面时,如果用户未登录,

则跳转至系统登录页,登录成功后,跳转到用户之前访问的页面。

 

实现步骤:

1.新建一个登录拦截器:LoginInterceptor.java,注意拦截器顶部的@Component注解

package com.rc.controller;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

@Component
public class LoginInterceptor implements HandlerInterceptor {
    private static final String LOGIN_URL = "/login";

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        Object username = request.getSession().getAttribute("username");
        if (username == null || "".equals(username.toString())) {

            //构造登录成功后跳转页面
            String path = request.getRequestURI();
            String parm = request.getQueryString();
            String returnUrl = path;
            if (parm != null && !parm.equals("")) {
                returnUrl = path + "?" + parm;
            }

            //重定向到登录页,附加returnurl参数
            response.sendRedirect(
                    request.getSession().getServletContext()
                            .getContextPath()
                            + LOGIN_URL + "?returnurl=" + URLEncoder.encode(returnUrl)
            );
            return false;
        }
        return true;
    }
}

示例代码中是通过session来验证用户是否登录。

2.新建针对登录过滤器的配置类:LoginConfiguration.java

package com.rc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class LoginConfiguration implements WebMvcConfigurer {
    public final LoginInterceptor LoginInterceptor;

    public LoginConfiguration(LoginInterceptor loginInterceptor) {
        this.LoginInterceptor = loginInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加对用户未登录的拦截器,并添加排除项
        registry.addInterceptor(LoginInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/content/**")//排除样式、脚本、图片等资源文件
                .excludePathPatterns("/login","/login-form")
                .excludePathPatterns("/", "/index");

    }

}

在这里可以指定哪些路径是需要登录验证的,哪些路径不需要登录验证。我这里使用的是Spring MVC 2.7.6 版本,可以通过代码来配置,不用去配置xml文件了。

附:

1.登录Controller参考代码:

package com.rc.controller;

import com.rc.model.AjaxResult;
import com.rc.model.ConnectionInfo;
import com.rc.util.SqlServerHelper;
import org.apache.tomcat.Jar;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Controller
public class HomeController extends BaseController {
    @RequestMapping("/")
    public String index() {
        return "/login";
    }

    @RequestMapping("/index")
    public String index2() {
        return "/login";
    }

    @RequestMapping("/login")
    public String login() {
        return "/login";
    }

    @RequestMapping("/logout")
    public String logout(HttpServletRequest request) {
        request.getSession().setAttribute("username", "");
        return "/login";
    }


    @RequestMapping("/login-form")
    @ResponseBody
    public String loginfrom(HttpServletRequest request) {
        String name = request.getParameter("name");
        String pass = request.getParameter("pass");
        AjaxResult result = new AjaxResult();
        if (name == null || name.equals("")) {
            result.setIsSuccess(false);
            result.setBody("抱歉,用户名不能为空!");
            return new JSONObject(result).toString();
        }
        if (pass == null || pass.equals("")) {
            result.setIsSuccess(false);
            result.setBody("抱歉,密码不能为空!");
            return new JSONObject(result).toString();
        }
        ConnectionInfo con = new ConnectionInfo();
        con.setServer("192.168.1.1");
        con.setDbName("******");
        con.setPort("1433");
        con.setUserName("******");
        con.setPassword("******");

        SqlServerHelper sql = InitSqlServer(con);
        pass = getMD5Str(pass);
        String json = sql.QueryJson("select * from Usertable where username=? and psw=?", new String[]{name, pass});
        if (json != null) {
            try {
                JSONArray arr = new JSONArray(json);
                if (arr.length() > 0) {
                    JSONObject o = arr.getJSONObject(0);
                    result.setIsSuccess(true);
                    result.setBody("验证通过");
                    request.getSession().setAttribute("username", o.getString("username"));
                    return new JSONObject(result).toString();
                } else {
                    result.setIsSuccess(false);
                    result.setBody("抱歉,用户名或密码错误!");
                    return new JSONObject(result).toString();
                }
            } catch (Exception ex) {
                result.setIsSuccess(false);
                result.setBody("抱歉,请求异常" + ex.getMessage());
                return new JSONObject(result).toString();
            }
        } else {
            result.setIsSuccess(false);
            result.setBody("抱歉,用户名或密码错误!");
            return new JSONObject(result).toString();
        }
    }

    public static String getMD5Str(String str) {
        byte[] digest = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("md5");
            digest = md5.digest(str.getBytes("utf-8"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //16是表示转换为16进制数
        String md5Str = new BigInteger(1, digest).toString(16);
        return md5Str;
    }

    public static SqlServerHelper InitSqlServer(ConnectionInfo con) {
        String connection = "jdbc:sqlserver://" + con.getServer() + ":" + con.getPort() + ";DatabaseName=" + con.getDbName();
        String userName = con.getUserName();
        String password = con.getPassword();
        SqlServerHelper helper = new SqlServerHelper(connection, userName, password);
        return helper;
    }

}

2.SqlServerHelper.java

package com.rc.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.RowSet;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;

import org.json.JSONObject;

public class SqlServerHelper {
	private String _connection;
	private String _userName;
	private String _password;

	/**
	 * 构造函数,传入数据库地址和账户信息
	 *
	 * @param connection 如:jdbc:sqlserver://localhost:1433;DatabaseName=Test
	 * @param userName   如:sa
	 * @param password   如:123456
	 */
	public SqlServerHelper(String connection, String userName, String password) {
		_connection = connection;
		_userName = userName;
		_password = password;
	}

	private Connection getConnection() {
		try {
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
			Connection conn = (Connection) DriverManager.getConnection(_connection, _userName, _password);
			return conn;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private void closeCon(Connection conn, PreparedStatement pstm, ResultSet rs) {
		try {
			if (conn != null) {
				conn.close();
			}
			if (pstm != null) {
				pstm.close();
			}
			if (rs != null) {
				rs.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public RowSet Query(String sql, String[] params) {
		Connection conn = null;
		PreparedStatement pstm = null;
		try {
			conn = getConnection();
			pstm = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					pstm.setString(i + 1, params[i]);
				}
			}
			ResultSet rs = pstm.executeQuery();
			RowSetFactory factory = RowSetProvider.newFactory();
			CachedRowSet cachedRs = factory.createCachedRowSet();
			// 使用ResultSet装填RowSet
			cachedRs.populate(rs);
			rs.close();
			pstm.close();
			conn.close();
			return cachedRs;

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeCon(conn, pstm, null);
		}
		return null;
	}

	/**
	 * 执行单个数据库操作 Insert,Update,Delete
	 * 
	 * @return 成功执行的记录数
	 */
	public Integer Update(String sql, String[] params) {
		Connection conn = null;
		PreparedStatement pstm = null;

		try {
			conn = getConnection();
			pstm = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					pstm.setString(i + 1, params[i]);
				}
			}
			return pstm.executeUpdate();

		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		} finally {
			closeCon(conn, pstm, null);
		}
	}

	/**
	 * 执行多个数据库操作,包含事务处理功能
	 * 
	 * @return 如果事务执行成功返回1,如果事务执行不成功返回0
	 */
	public Integer Update(String[] sqls, String[][] params) {
		Connection conn = null;
		PreparedStatement pstm = null;
		try {
			conn = getConnection();
			// 禁止自动提交事务
			conn.setAutoCommit(false);
			for (int i = 0; i < sqls.length; i++) {
				pstm = conn.prepareStatement(sqls[i]);
				if (params != null) {
					for (int j = 0; j < params[i].length; j++) {
						pstm.setString(j + 1, params[i][j]);
					}
				}
				pstm.executeUpdate();
			}
			conn.commit();
			return 1;
		} catch (Exception e) {
			e.printStackTrace();
			try {
				conn.rollback();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			return 0;
		} finally {
			closeCon(conn, pstm, null);
		}
	}

	/**
	 * 执行SQL语句,返回JSON结果(不带参数)
	 */
	public String QueryJson(String sql) {
		Connection conn = getConnection();
		Statement stmt;
		try {
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			String json;
			try {
				json = resultSetToJson(rs);
				return json;
			} catch (Exception e) {
				rs.close();
				stmt.close();
				conn.close();
				e.printStackTrace();
				return e.getMessage();
			}
		} catch (SQLException e) {

			e.printStackTrace();
			return e.getMessage();
		}
	}

	/**
	 * 执行SQL语句,返回JSON结果(带参数)
	 */
	public String QueryJson(String sql, String[] params) {
		Connection conn = null;
		PreparedStatement pstm = null;
		try {
			conn = getConnection();
			pstm = conn.prepareStatement(sql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					pstm.setString(i + 1, params[i]);
				}
			}
			ResultSet rs = pstm.executeQuery();
			String json = resultSetToJson(rs);
			return json;
		} catch (Exception e) {
			e.printStackTrace();
			return e.toString();
		} finally {
			closeCon(conn, pstm, null);
		}
	}

	public Object ExecuteScalar(String sql) {
		Object value = null;
		RowSet rs;
		try {
			rs = Query(sql);

			if (rs != null) {
				rs.next();
				value = rs.getObject(1);
			}
			return value;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public Object ExecuteScalar(String sql, String[] params) {
		Object value = null;
		try {
			RowSet rs = Query(sql, params);
			if (rs != null) {
				rs.next();
				value = rs.getObject(1);
				return value;
			}
		} catch (Exception e) {
			return value;
		}
		return value;
	}

	public RowSet Query(String sql) {
		Connection conn = getConnection();
		Statement stmt;
		try {
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(sql);
			RowSetFactory factory = RowSetProvider.newFactory();
			CachedRowSet cachedRs = factory.createCachedRowSet();
			cachedRs.populate(rs);
			rs.close();
			stmt.close();
			conn.close();
			return cachedRs;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public String resultSetToJson(ResultSet rs) throws SQLException, Exception {
		org.json.JSONArray array = new org.json.JSONArray();
		ResultSetMetaData metaData = rs.getMetaData();
		int columnCount = metaData.getColumnCount();

		while (rs.next()) {
			JSONObject jsonObj = new JSONObject();

			for (int i = 1; i <= columnCount; i++) {
				String columnName = metaData.getColumnLabel(i);
				String value = rs.getString(columnName);
				jsonObj.put(columnName, value);
			}
			array.put(jsonObj);
		}

		String json = array.toString();
		return json;
	}
}

3.login视图:login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>****系统-用户登录</title>
    <link th:href="@{/content/img/favicon.ico}" rel="shortcut icon" type="image/x-icon"/>
    <script th:src="@{/content/jquery-easyui-1.7.4/jquery.min.js}"></script>
    <link rel="stylesheet" th:href="@{/content/font-awesome-4.7.0/css/font-awesome.css}">
    <script th:inline="javascript" type="text/javascript">
        var _root = [[${#request.getContextPath()}]];
    </script>
    <style type="text/css">
        * {font-size: 14px;}

        td {padding: 5px;}

        .main {width: 80%;margin: 40px auto;}

        input[type="text"], input[type="password"] {
            border: 1px solid #ccc;padding: 5px 5px;outline: none; border-radius: 3px;
        }

        .btnLogin { background: brown;
            color: white;
            border: 0;
            padding: 5px 10px;
            border-radius: 3px;}
    </style>
</head>
<body>
<div class="main">
    <table style="margin: 0 auto;">
        <tr>
            <td colspan="2" style="text-align: center;font-size: 16px;padding: 20px 0;">
                <b style="letter-spacing: 5px;font-size: 22px;line-height: 45px;"> ****系统<br/>用户登录</b>
                <span style="color:gray;font-size: 12px;display: block;text-align: center;margin: 10px 0">(请使用****账号登录)</span>
            </td>
        </tr>
        <tr>
            <td style="text-align: right">用户名:</td>
            <td><input type="text" name="username"/></td>
        </tr>
        <tr>
            <td style="text-align: right"> 密&emsp;码:</td>
            <td><input type="password" name="password"/></td>
        </tr>
        <tr>
            <td></td>
            <td>
                <input type="button" value="登录" class="btnLogin"/>
            </td>
        </tr>
    </table>
    <script type="text/javascript">
        $(function () {
            $(".btnLogin").click(function () {
                var name = $("[name='username']").val();
                var pass = $("[name='password']").val();
                if (name.length == 0) {
                    alert("请输入用户名!");
                    return;
                }
                if (pass.length == 0) {
                    alert("请输入密码!");
                    return;
                }
                $.ajax({
                    url: _root + "/login-form",
                    type: "post",
                    data: {
                        name: name,
                        pass: pass
                    },
                    success: function (res) {
                        res = JSON.parse(res);
                        if (res.isSuccess) {
                            var returnurl = getQueryString("returnurl");
                            if (returnurl&&returnurl.length > 0 && returnurl.indexOf("/logout") == -1) {
                                window.location = returnurl;
                            } else {
                                window.location = _root + "/con/list";
                            }
                        } else {
                            alert(res.body);
                        }

                    }
                });
            });
        })

        function getQueryString(name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            var reg_rewrite = new RegExp("(^|/)" + name + "/([^/]*)(/|$)", "i");
            var r = window.location.search.substr(1).match(reg);
            var q = window.location.pathname.substr(1).match(reg_rewrite);
            if (r != null) {
                return unescape(r[2]);
            } else if (q != null) {
                return unescape(q[2]);
            } else {
                return null;
            }
        }
    </script>

</div>
</body>
</html>

发表评论

电子邮件地址不会被公开。 必填项已用*标注