过滤器的配置:
在web.xml下面添加如下配置
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>***.**.***.******.****.LoginFilter</filter-class>(自己指定自己的过滤器路径啊)
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>*.do</url-pattern>//在这里定义你的过滤对象(一般为.html和.do,前者为对访问页面的过滤,后者是对服务的过滤,一定要考虑好了再做,对于页面的过滤是可以直接跳转页面的(转发/重定向都OK),ajax服务的话没有办法直接进行页面的跳转)
</filter-mapping>
session的配置:
<session-config>
<session-timeout>1</session-timeout>(开发使用,所有设置session时长为1分钟,便于测试)
</session-config>
编写(自定义)过滤器:实现filter接口
public class LoginFilter implements Filter{
private static final Log logger = LogFactory.getLog(LoginFilter.class);/日志
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
在doFilter中描述你的过滤器代码逻辑
问题1:request.getInputStream对象只能用1次,在filter中进行预登陆后chain.dofilter报错
解决方案:https://blog.csdn.net/dream8062/article/details/72674559
问题2:在过滤器中注入服务(服务的加载在过滤器之后,所以依赖注入等都是无效的)
解决方案:根据不同的框架,其解决方案都是不同的,所以在这里不予具体阐述,大多选择的beanFactory来进行处理
问题3:前台采用html的话ajax服务无法获取后台session数据(没有找到更好的解决方式,有的话请留言我,万分感激)
解决方式:https://blog.csdn.net/lasting_5/article/details/51958065
大概内容就是如上,下面是具体代码实现
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
HttpSession session = request.getSession();
//备份HttpServletRequest(解决问题1)
HttpServletRequest httpRequest = (HttpServletRequest)request;
httpRequest = new BufferedServletRequestWrapper(httpRequest);
//转换为json格式存放(要求传递值必须为json格式,否则会报错的哟)
JSONObject jsonObject = getLoginUser(httpRequest);
//请求的服务名
String doAction = request.getServletPath();
//本服务用于查询登录,不校验user_code
if(doAction.equals("/xxxLoginAction.do")){ //登录,对用户进行存储
String name = jsonObject.getString("login_name");
String pwd = jsonObject.getString("login_pwd");
//注入服务(框架不同,不具有通用性)
Injector injector = new Injector(Stage.PRODUCTION);
UserDaoService userDaoS = injector.getBean(UserDaoService.class);
//登录验证
UserInfo userInfo = userDaoS.getUser(name,pwd);
if(userInfo==null){
session.setAttribute("load_error", "LOAD_ERROR");//用户名或密码错误
}else{
String ip = getRelIp(request);
logger.error("******用户[{}]登录!******", "user_code:"+user_code+","+"ip:"+ip);
session.setAttribute("user_code", user_code);
session.removeAttribute("load_error");
arg2.doFilter(httpRequest, arg1);
return;
}
}else{
if(session.getAttribute("user_code")!=null){
arg2.doFilter(httpRequest, arg1);
}else{
session.setAttribute("load_error", "TIME_OUT"); //超时访问
}
}
//存在登录错误、超时、非法访问(解决问题3)
if(session.getAttribute("load_error")!=null){
String path = request.getContextPath();
String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";
response.setHeader("LOAD_ERROR", (String) session.getAttribute("load_error"));
response.setHeader("CONTEXTPATH", basePath+"login.html");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
//获取真实IP(还需优化)
private String getRelIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
//获取登录信息
private JSONObject getLoginUser(HttpServletRequest request) throws IOException{
StringBuilder content = new StringBuilder();
ServletInputStream reader = request.getInputStream();
byte[] b = new byte[1024];
int lens = -1;
while((lens=reader.read(b))>0){
content.append(new String(b, 0, lens));//将参数放到StringBuilder中
}
reader.close();
return JSONObject.parseObject(content.toString());
}
其他的代码就没什么好贴的啦,就是另外两个老哥blog里面的内容理解一下就OK了!