单台web app 做登陆很简单,放到session里就可以。但稍微大的应用都是apache下挂着多台tomcat的,tomcat1的session 到tomcat2下就不管用了。tomcat间的session复制也比较费性能,我们尽量要保持web层的无状态。
上一篇apache_tomcat负载均衡配置完成后,我基于此业余做了基于struts的多台应用登陆/自动登陆处理,源码在附件中。
原理:
1、登陆后把信息用户名及密码加密放入cooekis(如果选择自动登陆),同时把User 对象放入session。下上文中通过session.getAttribute("User")来判断是否登陆
2、在访问时会有两个拦截器来处理
a.loginInterceptor
从cookies中取得加密过的username和password,验证是否正确,将Uesr放入session
b.authInterceptor
对需要登陆才能有的操作加入验证处理,如果没登陆将跳转到登陆页,登陆完成后跳转要操作的页面。
代码实现:
1、LoginInterceptor
/**
*
* 从cookies中恢复登陆
*
* @author 锅巴
* @version 1.0 2010-6-29
*/
public class LoginInterceptor implements Interceptor {
public final static String CRYPTO_PWD = "865azo@44536_t";
private UserDAO userDAO;
public String intercept(ActionInvocation arg0) throws Exception {
printCookies();
process(arg0);
return arg0.invoke();
}
private void process(ActionInvocation arg0) throws Exception {
Map session = arg0.getInvocationContext().getSession();
if(session != null && session.get(Statics.USER_SESSION_KEY) != null){
System.out.println("========== user is have in session ");
return ;
}
HttpServletRequest request = ServletActionContext.getRequest();
Cookie[] cookies = request.getCookies();
if(cookies == null)
return;
for (Cookie cookie : cookies) {
if (Statics.COOKIE_REMEMBERME_KEY.equals(cookie.getName())
&& !StringUtils.isEmpty(cookie.getValue())) {
String[] split = cookie.getValue().split("-");
String userName = DESCrypto.decrypt(split[0],CRYPTO_PWD);
String password = DESCrypto.decrypt(split[1],CRYPTO_PWD);
try {
User user = userDAO.attemptLogin(userName, password);
session.put(Statics.USER_SESSION_KEY, user);
} catch (UserNotFoundException e) {
}
}
}
}
private void printCookies(){
System.out.println("========= printCookies statrt ========");
Cookie[] cookies = ServletActionContext.getRequest().getCookies();
if(cookies != null){
for(Cookie cook : cookies){
System.out.println(cook.getName() + " : " + cook.getValue() + " : " + cook.getMaxAge() );
}
}
System.out.println("========= printCookies end ========");
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public void destroy() {
// TODO Auto-generated method stub
}
public void init() {
// TODO Auto-generated method stub
}
}
2、AuthInterceptor
/**
* 必须验证要登陆的拦截器
* @author 锅巴
* @version 1.0 2010-6-29
*/
public class AuthInterceptor implements Interceptor{
private final static String ACTH_ERROR_TO_URL = "forwardLogin";
private static Log log = LogFactory.getLog(AuthInterceptor.class);
public void destroy() {
// TODO Auto-generated method stub
}
public void init() {
// TODO Auto-generated method stub
}
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
Map session = arg0.getInvocationContext().getSession();
if(session == null || session.get(Statics.USER_SESSION_KEY) == null){
return getAuthErrorReturn(arg0);
}
return arg0.invoke();
}
private String getAuthErrorReturn(ActionInvocation arg0){
HttpServletRequest request = ServletActionContext.getRequest();
String urlValue = request.getRequestURL().toString();
if (request.getQueryString() != null)
urlValue += "?" + request.getQueryString();
request.setAttribute(Statics.AUTH_LOGIN_GO, urlValue);
log.debug("urlValue:" + urlValue);
return ACTH_ERROR_TO_URL;
}
}
3、Login 登陆action
/**
*
* 描述
*
* @author 锅巴
* @version 1.0 2010-7-5
*/
public class LoginAction extends ActionSupport implements SessionAware,CookiesAware,ServletResponseAware,ServletRequestAware{
private Map session;
private Map cookie;
private HttpServletResponse response;
private UserDAO userDAO;
private String username;
private String password;
private String goUrl;
private HttpServletRequest request;
private boolean rememberMe;
public boolean isRememberMe() {
return rememberMe;
}
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
@Override
public void setServletRequest(HttpServletRequest arg0) {
// TODO Auto-generated method stub
this.request = arg0;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public String getGoUrl() {
return goUrl;
}
public void setGoUrl(String goUrl) {
this.goUrl = goUrl;
}
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;
}
@Override
public void setServletResponse(HttpServletResponse arg0) {
// TODO Auto-generated method stub
this.response = arg0;
}
@Override
public void setSession(Map arg0) {
// TODO Auto-generated method stub
this.session = arg0;
}
@Override
public void setCookiesMap(Map arg0) {
// TODO Auto-generated method stub
this.cookie = arg0;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
public String postLogin() throws Exception {
User user = null;
try{
user = userDAO.attemptLogin(username, password);
}catch(UserNotFoundException ex){
addActionError("登陆失败!");
return INPUT;
}
processCookie(user);
return SUCCESS;
}
private void processCookie(User user) throws Exception {
session.put(Statics.USER_SESSION_KEY, user);
//cookie value 不能有==这种情况,不能ie会拒绝该cookies
Cookie cookie = new Cookie(Statics.COOKIE_REMEMBERME_KEY, DESCrypto.desCrypto(username.getBytes(), LoginInterceptor.CRYPTO_PWD)+ "-" + DESCrypto.desCrypto(password.getBytes(), LoginInterceptor.CRYPTO_PWD));
if (rememberMe){
cookie.setMaxAge(60 * 60 * 24 * 14);
}else{
cookie.setMaxAge(0);
}
cookie.setPath("/");
cookie.setDomain("t.com");
response.addCookie(cookie);
}
}
4、LoginOut 退出action
/**
*
* 描述
*
* @author 锅巴
* @version 1.0 2010-7-5
*/
public class LoginOutAction extends ActionSupport implements ServletResponseAware,ServletRequestAware{
private HttpServletResponse response;
private HttpServletRequest request;
@Override
public void setServletResponse(HttpServletResponse arg0) {
// TODO Auto-generated method stub
this.response=arg0;
}
@Override
public void setServletRequest(HttpServletRequest arg0) {
// TODO Auto-generated method stub
this.request = arg0;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
Cookie[] cookies = request.getCookies();
if (cookies!=null) {
for (Cookie cookie : cookies) {
if (Statics.COOKIE_REMEMBERME_KEY.equals(cookie
.getName())) {
//清除cookie时要与增加时步骤一致 如path,domain
cookie.setPath("/");
cookie.setDomain("t.com");
cookie.setValue("");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
HttpSession session = request.getSession(false);
if (session!=null)
session.removeAttribute(Statics.USER_SESSION_KEY);
System.out.println("============== login out ================");
return SUCCESS;
}
}
5、struts.xml配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="loginInterceptor" class="com.my.interceptor.LoginInterceptor"></interceptor>
<interceptor name="authInterceptor" class="com.my.interceptor.AuthInterceptor"></interceptor>
<!-- 默认拦截器堆栈 -->
<interceptor-stack name="loginDefaultStack">
<interceptor-ref name="loginInterceptor"></interceptor-ref>
<interceptor-ref name="authInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
<!-- 需要登陆验证的拦截器堆栈 -->
<interceptor-stack name="autowireDefault">
<interceptor-ref name="loginInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="autowireDefault"></default-interceptor-ref>
<global-results>
<!-- 验证未通过跳转全局result -->
<result name="forwardLogin" type="chain">
<param name="actionName">forwardLogin</param>
<param name="namespace">/common</param>
</result>
</global-results>
</package>
<include file="struts-conf/common.struts.xml"></include>
</struts>
6、common.struts.xml 配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="common" namespace="/common" extends="default">
<!-- 跳转登录 -->
<action name="forwardLogin" class="com.my.action.JumpLoginAction">
<result name="success" type="redirect">
/common/login.html?goUrl=${goUrl}
</result>
</action>
<!-- 登陆页面 -->
<action name="login" class="com.my.action.LoginAction">
<result name="success" type="dispatcher">
/common/login.jsp
</result>
</action>
<!-- 退出 -->
<action name="loginOut" class="com.my.action.LoginOutAction">
<result name="success" type="dispatcher">
/common/login_out.jsp
</result>
</action>
<!-- 登陆post操作 -->
<action name="postLogin" class="com.my.action.LoginAction" method="postLogin">
<result name="success" type="redirect">
${goUrl}
</result>
<result name="input" type="dispatcher">
/common/login.jsp
</result>
<interceptor-ref name="autowireDefault" />
<interceptor-ref name="validationWorkflowStack" />
</action>
<!-- 需要登陆验证的页面 -->
<action name="home" class="com.my.action.HomeAction">
<result name="success" type="dispatcher">
/index.jsp
</result>
<interceptor-ref name="loginDefaultStack" />
</action>
</package>
</struts>
注意事项:
1、LoginAction-postLogin-validation.xml ,可以按action 方法名来验证。
2、cookies 中不能含有"==",否则IE会写不进去。
3、写cookies与清cookies的操作要完全一致,否则清不了。
如:
写cookies
//cookie value 不能有==这种情况,不能ie会拒绝该cookies
Cookie cookie = new Cookie(Statics.COOKIE_REMEMBERME_KEY, DESCrypto.desCrypto(username.getBytes(), LoginInterceptor.CRYPTO_PWD)+ "-" + DESCrypto.desCrypto(password.getBytes(), LoginInterceptor.CRYPTO_PWD));
if (rememberMe){
cookie.setMaxAge(60 * 60 * 24 * 14);
}else{
cookie.setMaxAge(0);
}
cookie.setPath("/");
cookie.setDomain("t.com");
response.addCookie(cookie);
清cookies
cookie.setPath("/");
cookie.setDomain("t.com");
cookie.setValue("");
cookie.setMaxAge(0);
response.addCookie(cookie);
分享到:
相关推荐
Struts是Java EE领域中一款经典的MVC框架,它为构建Web应用程序提供了强大的支持,尤其在处理表单提交、请求转发、以及业务逻辑与视图分离等方面表现卓越。本资源"使用Struts快速实现web开发的登陆工程源程序"正是...
本文将深入探讨“Android客户端远程登录Web服务器数据交换实例”,讲解如何使用MySQL数据库、JSON数据传输以及Struts2、JavaBean和Servlet等技术。 首先,让我们了解一下MySQL数据库。MySQL是一款开源的关系型...
在这个例子中,我们将深入探讨如何在MyEclipse环境下使用Struts2框架与CAS服务器配合,实现单点登录功能。 首先,让我们理解一下CAS(Central Authentication Service)的核心概念。CAS是一个开放源码的SSO解决方案...
Struts和Hibernate是两种在Java Web开发中广泛使用的开源框架,它们在构建高效、可维护的Web应用程序中扮演着重要角色。Struts是MVC(Model-View-Controller)架构的实现,主要用于处理用户请求和控制业务逻辑,而...
总的来说,"struts 当当网项目 web"是一个基于Struts 1.2的Web项目,它涉及到MVC设计模式、数据库交互、自定义Struts实现等多个方面的知识。通过深入研究这个项目,开发者可以提升对Struts框架的理解,以及在实际...
Struts2是一个强大的MVC(模型-视图-控制器)框架,它被广泛应用于Java Web开发中,提供了灵活的控制层来处理用户请求并管理业务逻辑。在这个项目中,"Struts2无刷新实现登陆退出"是通过整合Struts2框架、JavaScript...
Struts2是一个基于MVC(Model-View-Controller)设计模式的Java web框架,它使得开发者可以更方便地处理HTTP请求和响应。在本场景中,我们关注的是如何使用Struts2实现图片上传到服务器,并且能异步加载显示这些图片...
Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它主要负责处理MVC(Model-View-Controller)架构中的Controller部分。本项目是一个基于Struts1的简单登录系统,用于展示如何在Tomcat服务器上运行...
学习Java Web开发首先要掌握Java的基础语法、类、对象、接口、异常处理以及多线程等核心概念。在实际项目中,Java的Servlet和JSP(JavaServer Pages)是处理HTTP请求和生成动态内容的主要工具,它们为Web应用提供了...
- 讲解了如何部署Struts应用程序到Web服务器上,如Tomcat或Jetty。 **3.2 Java Web应用配置文件:web.xml** - **3.2.1 Java Web应用配置文件概述** - web.xml是Java Web应用程序的核心配置文件,用于描述应用...
Struts2是一个强大的Java EE应用程序框架,用于构建和部署企业级Web应用。它基于MVC(Model-View-Controller)设计模式,简化了Java Servlet API的复杂性,提供了丰富的功能来处理请求、响应以及业务逻辑。在这个...
此外,自定义JSP标签可以扩展JSP的功能,XML用于数据交换和配置,Web服务器和应用服务器如Tomcat或WebLogic则负责部署和运行Java Web应用。 在Java Web应用的MVC架构中,View(视图)负责呈现用户界面,Controller...
在Java的Struts框架下进行Web编程,主要是为了构建基于MVC(模型-视图-控制器)模式的Web应用程序。Struts是一个强大的、开源的Java框架,它简化了开发过程,提高了代码的可维护性和可扩展性。Struts2是其最新版本,...
例如,可以查看`org.apache.struts.upload.MultipartRequestHandler`类来了解其如何处理多部分请求,以及`org.apache.struts.upload.CommonsMultipartRequestHandler`(如果使用了Apache Commons FileUpload库)是...
Struts2是一个强大的MVC(Model-View-Controller)框架,广泛用于构建Java Web应用程序。在现代Web开发中,JSON(JavaScript Object ...这将有助于提升你在Web开发中的技能,特别是处理服务器与客户端之间的数据交互。
- 私有文件:不被Web服务器返回的文件。 Struts 2问题领域 Struts 2框架解决了多个Web开发中的问题领域: - 应用程序逻辑与标记的分离:使得更改和维护变得更容易,并且更易于重用。这样的分离也减少了出错的可能...
2. **welcome file设置无效**:Web应用通常会在`web.xml`中定义一个或多个欢迎文件列表,这些文件将被服务器自动加载显示。但是,在Struts2框架中,即使设置了welcome file,也可能因为Struts2的拦截机制而无法直接...
同时,还需要考虑Web应用的部署,如WEB-INF目录下的web.xml配置,以及项目的打包和运行。 这个项目展示了Struts2的基本应用和扩展能力,适合初学者学习和实践,了解如何在实际项目中运用Struts2来构建完整的功能...
总之,Struts2和WebOffice的结合,为企业级Web应用提供了一种高效、便捷的在线文档处理解决方案。通过理解这两个组件的工作原理,开发者可以构建出功能强大的文档管理系统,满足用户在云端编辑、分享和协作的需求。...