SSH网上商城项目实战 过滤器实现购物车购物登陆功能的判断。
2016-05-23 14:55
776 查看
上一节我们做完了购物车的基本操作,但是有个问题是:当用户点击结算时,我们应该做一个登录的判断,判断用户有没有登录,没有登录的话,得首先让用户登录。这就用到了过滤器的技术了,过滤器是专门拦截页面请求的,它与拦截器的原理差不多,拦截器是专门拦截Action请求的,所以各有所用,如果直接是页面的跳转,不经过Action的话,我们只要写一个拦截器即可,如果需要跳转到一个Action处理,那么我们就得写一个拦截器。
先说一下实现原理:写一个过滤器,在web.xml中配置一下需要拦截的url,这样的话,当用户的请求url中满足配置的话,就会执行我们自己写的过滤器,在过滤器中,我们首先检查session中有没有登录过的user,如果没有说明没有登录,然后拿到用户想要访问的页面url和参数,重新拼接成url放到session中,然后重定向到登陆页面,登录后跳转到Action处理,处理完后跳转到session中保存的url,即原来用户想去的地方。这样就完成了登陆的跳转了。
当现实购物车页面后,我们点击结账,它会自动跳转到订单确认的页面,如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/a0a1bb1613cfa8b0e77ee5aa11a3dda8)
但是此时如果用户没登录,我们肯定不能直接跳到订单确认页面,所以我们要用过滤器拦下来判断一下,下面写过滤器:
过滤器的实现要实现Filter接口,并覆写三个方法即可,其实我们主要要覆写其中一个方法即可。如下:
[java] view
plain copy
public class UserFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 判断当前session是否有用户信息
if(req.getSession().getAttribute("user") == null) {
//保存当前客户想要去的url地址
String goURL = req.getServletPath();//获得用户想要去的地址
String param = req.getQueryString(); //获得地址中携带的参数
if(param != null) {
goURL = goURL + "?" + param; //重新拼好请求地址+参数
}
//把当前客户想要访问的地址,存储到session中
req.getSession().setAttribute("goURL", goURL);
//非法请求,跳转到登陆页面
req.getSession().setAttribute("error", "非法请求,请登录!");
res.sendRedirect(req.getContextPath() + "/ulogin.jsp");
} else {
//如果有下一个过滤器则跳转,否则直接到目标页面
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig config) throws ServletException {
// TODO Auto-generated method stub
}
}
从实现的代码来看,主要腹泻了doFilter方法,在方法里,首先判断当前session中是否有用户的信息,如果没有,说明没有登录,那么要先将用户想要去的url地址和地址中的参数保存下来,拼成新的url存到session中,然后重定向到登陆页面,让用户登陆。如果session中有用户信息,说明已经登录过了,直接放行到用户想去的页面。
写好了Filter,别忘了在web.xml中配置要过滤的url,配置如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/15b47f22650b9e8154fcc884da81d169)
所以会过滤上面的${shop}/user/confirm.jsp。接下来我们看看登陆页面,其实就是两个框框,用户名和密码,主要看它跳到哪个Action去:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/72839525297b7bbb4565ca341c61817b)
我们看到,它跳转到了userAction中的login方法去执行逻辑。下面我们实现userAction:
在userAction中,我们首先进行登陆的判断,即在数据库中查找有没有该用户名和密码的用户,如果成功,则将user存到session中,然后返回一个结果,交给struts2处理,代码如下:
[java] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
@Controller("userAction")
@Scope("prototype")
public class UserAction extends BaseAction<User> {
public String login() {
//进行登陆的判断
model = userService.login(model);
if(model == null) {
session.put("error", "登陆失败");
return "login";
} else {
//登录成功,先将用户存储到session中
session.put("user", model);
//根据session中goURL是否有值而决定页面的跳转
if(session.get("goURL") == null) {
return "index"; //跳到首页
} else {
return "goURL";
}
}
}
}
我们看看struts.xml中的配置:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/dfd2a279682498f0998e7682ffd5fc77)
因为我们把goURL存在session中了,但是在struts.xml中我们不能像在Java代码里去拿session,然后拿参数,但是我们可以从值栈中取,上面是从值栈中取数据的方法。
Service层主要就是上面Action中用到的login方法,实现比较简单,如下:
[java] view
plain copy
//userService接口
public interface UserService extends BaseService<User> {
//用户登陆,成功返回该User
public User login(User user);
}
//userServiceImpl实现类
@Service("userService")
public class UserServiceImpl extends BaseServiceImpl<User> implements
UserService {
@Override
public User login(User user) {
String hql = "from User u where u.login=:login and u.pass=:pass";
return (User) getSession().createQuery(hql) //
.setString("login", user.getLogin()) //
.setString("pass", user.getPass()) //
.uniqueResult();
}
}
好了,这样我们用过滤器实现了用户登录的判断与跳转,登陆过后,就能跳转到订单确认页面了,效果如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/716f6853bf4d79c651ba9ccb37e84dd9)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/d5cdd597f6f99ca4506884c95d3dd4bc)
整个流程测试完毕,功能正常。其实这里还可以再完善一点,我们其实应该在加入购物车之前就应该要进行登录判断,也就是说,购物车页面的时候已经是登录状态了,这里是订单确认页面判断登录的。不过在购物车页面前进行判断的话,我们就不好用过滤器了,我们得用拦截器,因为跳转到购物车页面请求的是Action,不是普通页面,请求Action的时候我们得用拦截器拦截来判断,后期再来完善这里吧,现在先把这里的功能基本实现了再说~好了,登录判断与跳转就做好了。
(注:到最后我会提供整个项目的源码下载!欢迎大家收藏或关注)
1. 登录跳转的原理
先说一下实现原理:写一个过滤器,在web.xml中配置一下需要拦截的url,这样的话,当用户的请求url中满足配置的话,就会执行我们自己写的过滤器,在过滤器中,我们首先检查session中有没有登录过的user,如果没有说明没有登录,然后拿到用户想要访问的页面url和参数,重新拼接成url放到session中,然后重定向到登陆页面,登录后跳转到Action处理,处理完后跳转到session中保存的url,即原来用户想去的地方。这样就完成了登陆的跳转了。
2. 登录跳转的实现
当现实购物车页面后,我们点击结账,它会自动跳转到订单确认的页面,如下:但是此时如果用户没登录,我们肯定不能直接跳到订单确认页面,所以我们要用过滤器拦下来判断一下,下面写过滤器:
2.1 过滤器的实现
过滤器的实现要实现Filter接口,并覆写三个方法即可,其实我们主要要覆写其中一个方法即可。如下:[java] view
plain copy
public class UserFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 判断当前session是否有用户信息
if(req.getSession().getAttribute("user") == null) {
//保存当前客户想要去的url地址
String goURL = req.getServletPath();//获得用户想要去的地址
String param = req.getQueryString(); //获得地址中携带的参数
if(param != null) {
goURL = goURL + "?" + param; //重新拼好请求地址+参数
}
//把当前客户想要访问的地址,存储到session中
req.getSession().setAttribute("goURL", goURL);
//非法请求,跳转到登陆页面
req.getSession().setAttribute("error", "非法请求,请登录!");
res.sendRedirect(req.getContextPath() + "/ulogin.jsp");
} else {
//如果有下一个过滤器则跳转,否则直接到目标页面
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig config) throws ServletException {
// TODO Auto-generated method stub
}
}
从实现的代码来看,主要腹泻了doFilter方法,在方法里,首先判断当前session中是否有用户的信息,如果没有,说明没有登录,那么要先将用户想要去的url地址和地址中的参数保存下来,拼成新的url存到session中,然后重定向到登陆页面,让用户登陆。如果session中有用户信息,说明已经登录过了,直接放行到用户想去的页面。
写好了Filter,别忘了在web.xml中配置要过滤的url,配置如下:
所以会过滤上面的${shop}/user/confirm.jsp。接下来我们看看登陆页面,其实就是两个框框,用户名和密码,主要看它跳到哪个Action去:
我们看到,它跳转到了userAction中的login方法去执行逻辑。下面我们实现userAction:
2.2 Action的实现
在userAction中,我们首先进行登陆的判断,即在数据库中查找有没有该用户名和密码的用户,如果成功,则将user存到session中,然后返回一个结果,交给struts2处理,代码如下:[java] view
plain copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
@Controller("userAction")
@Scope("prototype")
public class UserAction extends BaseAction<User> {
public String login() {
//进行登陆的判断
model = userService.login(model);
if(model == null) {
session.put("error", "登陆失败");
return "login";
} else {
//登录成功,先将用户存储到session中
session.put("user", model);
//根据session中goURL是否有值而决定页面的跳转
if(session.get("goURL") == null) {
return "index"; //跳到首页
} else {
return "goURL";
}
}
}
}
我们看看struts.xml中的配置:
因为我们把goURL存在session中了,但是在struts.xml中我们不能像在Java代码里去拿session,然后拿参数,但是我们可以从值栈中取,上面是从值栈中取数据的方法。
2.3 Service层的登陆判断
Service层主要就是上面Action中用到的login方法,实现比较简单,如下:[java] view
plain copy
//userService接口
public interface UserService extends BaseService<User> {
//用户登陆,成功返回该User
public User login(User user);
}
//userServiceImpl实现类
@Service("userService")
public class UserServiceImpl extends BaseServiceImpl<User> implements
UserService {
@Override
public User login(User user) {
String hql = "from User u where u.login=:login and u.pass=:pass";
return (User) getSession().createQuery(hql) //
.setString("login", user.getLogin()) //
.setString("pass", user.getPass()) //
.uniqueResult();
}
}
好了,这样我们用过滤器实现了用户登录的判断与跳转,登陆过后,就能跳转到订单确认页面了,效果如下:
整个流程测试完毕,功能正常。其实这里还可以再完善一点,我们其实应该在加入购物车之前就应该要进行登录判断,也就是说,购物车页面的时候已经是登录状态了,这里是订单确认页面判断登录的。不过在购物车页面前进行判断的话,我们就不好用过滤器了,我们得用拦截器,因为跳转到购物车页面请求的是Action,不是普通页面,请求Action的时候我们得用拦截器拦截来判断,后期再来完善这里吧,现在先把这里的功能基本实现了再说~好了,登录判断与跳转就做好了。
(注:到最后我会提供整个项目的源码下载!欢迎大家收藏或关注)
相关文章推荐
- Unity3d即时战斗之敌人AI和角色攻击
- 解决ORA-00904: invalid identifier标识符无效
- 网站的安全如何得到安全保障
- bugly 上传 符号表文件
- iPhone或iTouch的tabbar高,导航栏高
- (一)洞悉linux下的Netfilter&iptables:什么是Netfilter?
- IP_VFR-4-FRAG_TABLE_OVERFLOW
- hdu 5701 中位数计数
- jboss5优化
- ListView_ArrayAdapter、SimpleAdapter
- c++ STL vector map的使用
- Android AlarmManager实现不间断轮询服务
- {dede:field name='array' /}的简单用法示范
- iOS学习之——View的圆角设置
- iOS开发--内存管理--学习手动内存管理暂时抛弃ARC以及retain/assign知识
- photoshop图像处理技术(一)
- windows 7 x64搭建FTP服务器
- Memcache Brief Intro
- HDU 5696 区间的价值
- 前端涉及的所有知识体系