首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

关于重定向到登记或登录前的页面

2013-04-20 
关于重定向到注册或登录前的页面新人目前在参考传智播客itcastbbs项目的代码,用的是struts1,其中actionbas

关于重定向到注册或登录前的页面
新人目前在参考传智播客itcastbbs项目的代码,用的是struts1,其中actionbase里重写了actionforward 的 executre方法



public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws Exception {
try {
return super.execute(mapping, form, request, response);
}
// 如果没有权限执行某个方法
// FIXME 这里不起作用了,因为PrivilegeInterceptorDelegatingRequestProcessor是在Action外层,无权限异常在外层抛出
catch (PermissionDeniedException e) {
// 1. 如果未登陆, 转到登陆界面
if (!MemberAuthenticationUtils.isLoggedOn(request)) {
// 可以在登陆后再转到登陆前的页面, 这个页面地址可以放到 request 作用域中;
String unencodedReturnPath = (String) request.getAttribute(WebConstants.REQUEST_UNENCODED_RETURN_PATH);
// 转到登录页面
ReturnPathUtils.toLoginWithReturnPathDefaultIsCurrentRequestURI(request, response, unencodedReturnPath);
return null;
}

// 2. 如果已登陆, 抛出权限不足异常
throw e;
}
}





疑惑的有两点:1、WebConstants.REQUEST_UNENCODED_RETURN_PATH, 以下是这个类,它起什么作用呢,什么叫 登录成功后返回的路径(未编码的) 登录成功后返回的路径(编码的)?上面的代码为什么要取得这个String,还有这个String为什么会在request对象中?实在觉得不可思议


package cn.itcast.bbs.web;

/**
 * Web作用域变量存储时用到的常量。格式为:{标识}_{其他名称部分}<br>
 * 标识可以为以下值:<br>
 * PAGE、REQUEST、SESSION、APPLICATION 代表是相应的作用域的变量的KEY<br>
 * PARAMETER 代表是请求参数名称<br>
 * COOKIE 代表是Cookie的名称<br>
 * 
 * @author tyg
 */
public class WebConstants {

/** 主题类型列表 */
public static final String APPLICATION_TOPIC_TYPE_LIST = "APPLICATION_TOPIC_TYPE_LIST";

/** 当前登录用户 */
public static final String SESSION_LOGGED_ON_USER = "SESSION_LOGGED_ON_USER";

/** 登录成功后返回的路径 */
public static final String PARAMETER_RETURN_PATH = "PARAMETER_RETURN_PATH";

/** 自动登录的Cookie的名称 */
public static final String COOKIE_NAME_AUTO_LOGIN = "COOKIE_AUTO_LOGIN_ITCASTBBS";

// FIXME 以下要统一。
/** 登录成功后返回的路径(未编码的) */
public static final String REQUEST_UNENCODED_RETURN_PATH = "REQUEST_UNENCODED_RETURN_PATH";

/** 登录成功后返回的路径(已编码的) */
public static final String REQUEST_ENCODED_RETURN_PATH = "REQUEST_ENCODED_RETURN_PATH";

public static final String REQUEST_HAS_EXCEPTIONACTION = "REQUEST_HAS_EXCEPTIONACTION";

}




2、ReturnPathUtils调用的方法,以下是这个类的代码


public class ReturnPathUtils {

/**
 * 重定向到上一次访问的(注册或登录之前的)页面
 * 
 * @param request
 * @param response
 * @return 是否已重定向到之前页面(如果没有地址,就返回false)
 */
public static boolean rediectPreviousPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
return rediectPreviousPage(request, response, null);
}

public static boolean rediectPreviousPage(HttpServletRequest request, HttpServletResponse response, String returnPath)
throws IOException {
returnPath = ReturnPathUtils.getAndDecodeReturnPath(request, returnPath);


if (StringUtils.isBlank(returnPath)) {
return false;
}
// FIXME 如果是访问的loginUI,login,logout,就不用跳转了
if (returnPath.indexOf("/user.do?method=log") > 0) {
return false;
}

response.sendRedirect(returnPath);
return true;
}

/**
 * 重定向到登陆页面
 * 
 * @param request
 * @param response
 * @throws IOException
 */
public static void toLoginWithReturnPathDefaultIsCurrentRequestURI(HttpServletRequest request, HttpServletResponse response,
String unencodedReturnPath) throws IOException {
// returnPath
String returnPath = makeReturnPathDefaultUseCurrentRequestURI(request, unencodedReturnPath);

// LOGIN_USER_URL应是/user.do?method=loginUI
String loginUserUrl = DataDict.getString(DDConstants.LOGIN_USER_URL);
response.sendRedirect(request.getContextPath() + loginUserUrl //
+ "&src=login&" + WebConstants.PARAMETER_RETURN_PATH + "=" + returnPath);
}

/**
 * 重定向到登陆页面
 * 
 * @param request
 * @param response
 * @param returnPath
 * @throws IOException
 */
public static void toLoginWithReturnPath(HttpServletRequest request, HttpServletResponse response, String returnPath)
throws IOException {
// LOGIN_USER_URL应是/user.do?method=loginUI
String loginUserUrl = DataDict.getString(DDConstants.LOGIN_USER_URL);
response.sendRedirect(request.getContextPath() + loginUserUrl //
+ "&src=login&" + WebConstants.PARAMETER_RETURN_PATH + "=" + returnPath);
}

/**
 * 从request的参数中取出登陆成功后要返回的地址,正确解码后返回<br>
 * 使用 Base64 编码
 * 
 * @param request
 * @return
 * @throws IOException
 */
public static String getAndDecodeReturnPath(HttpServletRequest request, String returnPath) {
if (returnPath == null) {
returnPath = request.getParameter(WebConstants.PARAMETER_RETURN_PATH);
}
if (StringUtils.isBlank(returnPath)) {
return null;
}
byte[] buf = Base64.decodeBase64(returnPath.getBytes());
String decodedPath = new String(buf);
return decodedPath;
}

/**
 * 准备登陆成功后要返回的地址 returnPath。<br>
 * 如果传递的参数 unencodedReturnPath 为 null,则使用本次请求的地址。<br>
 * 地址使用 Base64 编码。
 * 
 * @param request
 * @param unencodedReturnPath 要进行处理的地址(未经编码),如果为 null,则使用本次请求的地址
 * @return 把 returnPath 编码后的结果
 */
@SuppressWarnings("unchecked")
public static String makeReturnPathDefaultUseCurrentRequestURI(HttpServletRequest request, String unencodedReturnPath) {
if (unencodedReturnPath == null) {
unencodedReturnPath = request.getRequestURL().toString();
Map<String, String[]> params = request.getParameterMap();
boolean isFirstFlag = true;
for (Entry<String, String[]> e : params.entrySet()) {
for (String value : e.getValue()) {


if (isFirstFlag) {
unencodedReturnPath += "?" + e.getKey() + "=" + value;
isFirstFlag = false;
} else {
unencodedReturnPath += "&" + e.getKey() + "=" + value;
}
}
}
}

return new String(Base64.encodeBase64(unencodedReturnPath.getBytes()));
}

/**
 * 准备登陆成功后要返回的地址 returnPath。<br>
 * 如果请求中没有传递表示returnPath参数,则使用 referer 指定的地址。<br>
 * 1,地址使用 Base64 编码。<br>
 * 2,在浏览器中直接输入地址访问时,就没有referer信息。
 * 
 * @param request
 * @return 把 returnPathParamName 编码后的结果
 */
public static String getReturnPathDefaultUseRefererHeaderValue(HttpServletRequest request) {
// 默认使用传递的returnPath值
String returnPath = request.getParameter(WebConstants.PARAMETER_RETURN_PATH);
if (StringUtils.isNotBlank(returnPath)) {
return returnPath;
}

// 如果没有指定returnPath, 则使用referer指定的地址
// 注:referer中包含参数
String referer = request.getHeader("Referer");
// referer不为null,且referer中的地址要是本站的中的
// FIXME 在部署后,地址为http://bbs.itcast.cn,使用80端口(可以不写),所以BaseUrl中应没有端口号
// FIXME 这样也不可以。问题是show_top中注销后,回到首页了,应再回到show_top。
if (StringUtils.isBlank(referer) || !referer.startsWith(WebAppUtils.getBaseAccessUrlWithoutPort(request))) {
return null;
}
   
return new String(Base64.encodeBase64(referer.getBytes()));
}
}




我们可以看到这个方法,我不知道这里编码的意义是什么……
public static void toLoginWithReturnPathDefaultIsCurrentRequestURI(HttpServletRequest request, HttpServletResponse response,
String unencodedReturnPath) throws IOException {
// returnPath
String returnPath = makeReturnPathDefaultUseCurrentRequestURI(request, unencodedReturnPath);

// LOGIN_USER_URL应是/user.do?method=loginUI
String loginUserUrl = DataDict.getString(DDConstants.LOGIN_USER_URL);
response.sendRedirect(request.getContextPath() + loginUserUrl //
+ "&src=login&" + WebConstants.PARAMETER_RETURN_PATH + "=" + returnPath);
}


另外恳请高人加我qq:547301517,很多问题想要请教,感激不尽
[解决办法]
先自己学习一下servlet的相关知识!

热点排行