浏览一个网页系统,因为系统有很多个网页,如果任意输入一个url,都能跳转到相应功能页面,那这样就乱套了。你怎么区分用户?怎么保证操作上下文的连贯性?
所以呢,在用户未登录或者离线之后,不论输入什么url,都要跳转到登录页面。
进行第一次登录以后,后面如果转到其他页面,则不会影响。
如果过了一段时间没有操作,例如断网了,继续操作的时候,已经处于logout状态,这时候要重新跳转到登录页面。
这其实就是通过过滤器filter实现的,原理是,在request session里保存用户状态。每次进入一个页面,都会先通过filter做判断,如果还未登录或者处于离线状态,则跳去登录页;反之,继续操作。
filter主要是三个方法
//该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。
public void doFilter (ServletRequest, ServletResponse, FilterChain)
//web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
public void init(FilterConfig filterConfig)
//Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。
public void destroy()
web.xml文件里配置filter
<servlet> <servlet-name>loginServlet</servlet-name>
<servlet-class>com.stydt.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping><servlet>
<servlet-name>logoutServlet</servlet-name>
<servlet-class>com.stydt.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>logoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>pemissionFilter</filter-name>
<filter-class>com.stydt.filter.PemissionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>pemissionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
登录的时候,在session里保存状态。
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
// 访问登录页面之前所访问的页面,可通过这个值跳转至之前的页面
String returnUri = request.getParameter("return_uri");
RequestDispatcher rd = null;
if (userName == null || password == null) {
request.setAttribute("msg", "用户名或密码为空");
} else {
if (userName.equals("stydt") && password.equals("123456")) {
/* 登录成功 */
// 将登录状态保存到session对象中
request.getSession().setAttribute("flag", "login_success");
/* 判断登录之前的上一个页面是否存在 */
if (returnUri != null) {
// 存在则跳转到登录之前的界面
rd = request.getRequestDispatcher(returnUri);
rd.forward(request, response);
} else {
// 不存在则跳转到首页
rd = request.getRequestDispatcher("/17/index.jsp");
rd.forward(request, response);
}
} else {
/* 登录失败 */
// 将登录状态修改为失败
request.getSession().setAttribute("flag", "login_error");
request.setAttribute("msg", "用户名或密码错误");
// 失败后跳转到登录界面
rd = request.getRequestDispatcher("/17/login.jsp");
rd.forward(request, response);
}
}
}
}
Filter里面做判断
public class PemissionFilter implements Filter {
public PemissionFilter() {
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 将请求与响应向下转换
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
// 获得访问界面的url文件地址
String servletPath = req.getServletPath();
HttpSession session = req.getSession();
// 获取登录状态
String flag = (String) session.getAttribute("flag");
/* 判断是否是登录页、首页、登录servlet */
if (servletPath != null && (servletPath.equals("/17/login.jsp") || servletPath.equals("/17/index.jsp") || servletPath.equals("/LoginServlet"))) {
// 是则直接转发到下一组件
chain.doFilter(request, response);
} else {
// 否,则验证登录状态
if (flag != null) {
if (flag.equals("login_success")) {
// 登录成功,直接转发到下一组件
chain.doFilter(request, response);
} else {
// 登录失败,跳转到登录页,并保证当前网页的url文件路径
req.setAttribute("msg", "登录失败");
req.setAttribute("return_uri", servletPath);
RequestDispatcher rd = req.getRequestDispatcher("/17/login.jsp");
rd.forward(req, res);
}
} else {
// 未登录,跳转到登录页,并保证当前网页的url文件路径
req.setAttribute("msg", "您尚未登录,请登录");
req.setAttribute("return_uri", servletPath);
RequestDispatcher rd = req.getRequestDispatcher("/17/login.jsp");
rd.forward(req, res);
}
}
}
public void destroy() {
}
}
参考资料:
Servlet 编写过滤器
https://www.runoob.com/servlet/servlet-writing-filters.html
Servlet过滤器---登录权限控制
https://www.cnblogs.com/xiaobaizhiqian/p/7606146.html
Servlet Filter用于在用户访问网页系统时实现登录权限控制。当用户未登录或离线时,所有请求都将重定向至登录页面。登录后,Filter会检查session中用户状态,允许合法用户继续操作。如果长时间无操作导致用户被注销,再次访问时也会被引导至登录页面。Filter的核心是通过web.xml配置、session状态管理和过滤器内的判断逻辑来实现这一功能。
789

被折叠的 条评论
为什么被折叠?



