个人心得:本人是一个普通211学生,最近看到互联网行业就业压力巨大,不断思考自己进步的空间,趁着放假将以前课上做的web网页完善一下,当时因为办的免听错过了一些重要的内容,老师当时问我这个你用session了吗?我直接懵掉,session是个啥?所以期末成绩也没有90分,只得了87,就因为这个细节扣了很多,今日无事,决定学习如何提高网页的安全性。
先上项目目录:
再上我写这个工程的项目文件,至于每个文件发挥的功能待会儿解释,现在先了解有什么东西:
1:LoginFilter.java(翻译一下就是登录拦截器,通过右键工程-new-Filter创建,它是核心)
package gaga;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet Filter implementation class LoginFilter
*/
@WebFilter(filterName = "loginFilter",urlPatterns = {"/user.jsp","/SELECT.jsp"},initParams = {
@WebInitParam(name = "encoding",value = "UTF-8"),
@WebInitParam(name = "loginPage",value = "login.jsp")
})
public class LoginFilter implements Filter{
private FilterConfig filterConfig;
private String encoding;
private String loginPage;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
this.loginPage = filterConfig.getInitParameter("loginPage");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//设置请求和响应的属性
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
//强转类型
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//判断会话域中是否有用户对象
if (req.getSession().getAttribute("loginUser")!=null) {
System.out.print("OK");
chain.doFilter(request, response);
}else {
req.setAttribute("msg", "非法请求!");
req.getRequestDispatcher("login.jsp").forward(request, response);
}
}
public void destroy() {
Filter.super.destroy();
}
}
2:loginServlet.java(通过右键工程-new-Servlet创建)
package gaga;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class loginServlet
*/
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
if (username.equals("admin")&&pwd.equals("123")) {
User user = new User(1, username, pwd);
req.setAttribute("loginUser", user);
req.getSession().setAttribute("loginUser",user);
req.getRequestDispatcher("/user.jsp").forward(req, resp);
}else {
req.setAttribute("msg","账号密码错误");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3: User.java(右键工程-new-Class)
package gaga;
public class User {
private int userid;
private String username;
private String password;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(int userid, String username, String password) {
super();
this.userid = userid;
this.username = username;
this.password = password;
}
}
4: 下载jstl.jar包,standard.jar包,这跟网页解析与tomcat运行都有直接关系,我是在菜鸟教程上找的下载链接,这里就不贴链接了,下载后,复制到我第一张图对应的位置。你可能会好奇mysql-connector-java-8.0.30.jar是干嘛的,不用在意,这是连接数据库用的,我这个应用也没用到数据库。
5:web.xml,我是通过创建工程时,自带的generate自动生成的,至于在哪,可以看看别人的博客
6:login.jsp(依旧右键工程-new-jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
登录
7:user.jsp(同上)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Title
id:${loginUser.userid}
name:${loginUser.username}
运行效果图:
①:运行login.jsp文件,密码输入123,之后点击登录:
跳转到了user.jsp
②:如果我直接打开user.jsp,而不去登录(也就是先运行login.jsp文件),你猜猜会怎样?
是的,它并不让我看到user.jsp的内容,而是直接给我弹回到了login.jsp(如果你事先运行了login.jsp,并登录进去了,就需重启tomcat再运行user.jsp,不然无法看到图示效果,因为session对象并没有因为你关闭了网页而被删除),安全性就大大滴提高了。
8:接下来我们开始剖析文件:
LoginFilter.java,是负责拦截请求的,意思是能不能访问,是它说了算,里面包括
@WebFilter(filterName = "loginFilter",urlPatterns = {"/user.jsp","/SELECT.jsp"},initParams = {
@WebInitParam(name = "encoding",value = "UTF-8"),
@WebInitParam(name = "loginPage",value = "login.jsp")
})
这里是在配置filterconfig,这里写的内容将会被public void init(FilterConfig filterConfig) 方法进行初始化,filterName是给拦截器取个名字,urlPatterns里面装的是哪些文件将被拦截器作用(SELECT.jsp可以删去,因为我没有这个文件连了数据库,而且我也没贴出来,不过也不影响运行),initParams里面是填写你想的参数,可以自定义,格式如图,name就是你给参数取得名字,value就是参数等于多少。
设置好WebFilter后,将会调用init 方法,这里就是把刚才自定义的initParameter参数取出来。
init只运行一次,也就是你点击运行工程的那一刻开始,它就被执行了。
然后,工程里面每打开一个网页就会执行doFilter,这张图的//判断会话域中是否有用户对象以上的内容都是套路不过得有,不然网页不知道怎么翻译你的内容重点在这个部分:
简单解释一下就是,如果session域得到的loginUser内容不为空,就可以访问,若是为空,则给你弹回到login.jsp,像chain.doFilter(request,response)也是个套路,必须得有,req.setAttribute方法跟你具体的jsp内容有关,这里不再赘述。
回到重点,我该从哪儿看到Session域里有没有loginUser呢?其实我们得将这个loginUser放到Session中,至于怎么放,反正没在LoginFilter.java中。在哪儿呢?
让我们将目光投向loginServlet.java
我在这里写上了req.getSession().setAttribute("loginUser",user);没错,我在这里将user这个对象作为值,传给了loginUser,这样我们就能通过req.getSession().getAttribute("loginUser")知道session域有个叫loginUser的对象,其值为user,而不是空,所以这个细节很重要,也是为啥实现安全访问的原因
9:让我们看向login.jsp
注意action="loginServlet",这里代表了表单提交的位置,与loginServlet的
@WebServlet("/loginServlet")相对应
整个过程就是:表单一提交,就跑到loginServlet文件下的@WebServlet("/loginServlet")包含的内容运行,当运行到req.getRequestDispatcher("/user.jsp").forward(req, resp);的时候,也就是请求跳转到user.jsp时,LoginFilter开始工作,因为它要管user.jsp,因为我们在Filter里面的urlPatterns把user.jsp放进去了,然后发现存在loginUser,就让你允许访问user.jsp。
如果你直接进入user.jsp就不行,因为loginUser没有任何东西
你看是不是就将jsp,Servlet,Filter三种文件联系起来了,也实现了未登录不能访问的功能。
#本文可供学习讨论,笔者水平有限,还望海涵,若读者有更好的理解,欢迎评论区分享,里面的函数作用可在网络上浏览,笔者未多加赘述。