天天看点

Liferay 启动过程分析1-重定向到 http://host:port/c

前几天搞了一个BUG,吧精力耗尽,也激发了我对Liferay这个框架内部的探究欲望。所以这几天端午节准备对Liferay框架启动过程进行深入研究,来满足自己的好奇心。

当我们在地址栏中访问http://localhost:8080时,因为Liferay应用本质上也是一个web应用,所以它会去找ROOT应用的web.xml,因为定义了<welcome-file-list>:

<welcome-file-list> 

        <welcome-file>index.html</welcome-file> 

        <welcome-file>index.jsp</welcome-file> 

    </welcome-file-list> 

所以,它会去找index.jsp:

... 

<% 

String redirect = null; 

LayoutSet layoutSet = (LayoutSet)request.getAttribute(WebKeys.VIRTUAL_HOST_LAYOUT_SET); 

if (layoutSet != null) { 

    long defaultPlid = LayoutLocalServiceUtil.getDefaultPlid(layoutSet.getGroupId(), layoutSet.isPrivateLayout()); 

    if (defaultPlid != LayoutConstants.DEFAULT_PLID) { 

        Layout layout = LayoutLocalServiceUtil.getLayout(defaultPlid); 

        ServicePreAction servicePreAction = (ServicePreAction)InstancePool.get(ServicePreAction.class.getName()); 

        ThemeDisplay themeDisplay = servicePreAction.initThemeDisplay(request, response); 

        redirect = PortalUtil.getLayoutURL(layout, themeDisplay); 

    } 

    else { 

        redirect = PortalUtil.getPathMain(); 

else { 

    redirect = PortalUtil.getHomeURL(request); 

if (!request.isRequestedSessionIdFromCookie()) { 

    redirect = PortalUtil.getURLWithSessionId(redirect, session.getId()); 

response.setHeader(HttpHeaders.LOCATION, redirect); 

response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); 

%> 

<html> 

<head> 

    <title></title> 

    <meta content="1; url=<%= redirect %>" http-equiv="refresh" /> 

</head> 

<body onload="javascript:location.replace('<%= redirect %>')"> 

</body> 

</html> 

其中,最值得看的就是<body onload="javascript:location.replace...),它会在DOM树加载完毕之后触发,那么我们感兴趣的是,这个<%=redirect%>到底是什么呢?

寻找<%=redirect%>的值

为此,我们去看上面那段代码,因为第一次登录,所以什么用户信息都没有,所以实际上走的是以下的代码段:

然后这段代码会调用PortalUtil中的:

public static String getPathMain() { 

        return getPortal().getPathMain(); 

然后调用PortalImpl类中的:

public String getPathMain() { 

    return _pathMain; 

而这个_pathMain是由该类中以下代码提供的,在PortalImpl构造器中:

// Paths 

_pathProxy = PropsValues.PORTAL_PROXY_PATH; 

_pathContext = ContextPathUtil.getContextPath(PropsValues.PORTAL_CTX); 

_pathContext = _pathProxy.concat(_pathContext); 

_pathFriendlyURLPrivateGroup = 

    _pathContext + _PRIVATE_GROUP_SERVLET_MAPPING; 

_pathFriendlyURLPrivateUser = 

    _pathContext + _PRIVATE_USER_SERVLET_MAPPING; 

_pathFriendlyURLPublic = _pathContext + _PUBLIC_GROUP_SERVLET_MAPPING; 

_pathImage = _pathContext + PATH_IMAGE; 

_pathMain = _pathContext + PATH_MAIN; 

// Groups 

所以_pathMain为_pathContext+PATH_MAIN ,我们依次来解析:

解析 _pathContext:

对于_pathContext,它是ContextPathUtil.getContextPath(PropsValues.PORTAL_CTX);

其中PropsValues.PORTAL_CTX是:

public static final String PORTAL_CTX = PropsUtil.get(PropsKeys.PORTAL_CTX); 

它会去找PropsKeys接口中的常量定义:

public static final String PORTAL_CTX = "portal.ctx"; 

然后找到并替换之后,去执行PropsUtil.get("portal.ctx");

public static String get(String key) { 

    return _instance._get(key); 

它会访问

private String _get(String key) { 

        return _getConfiguration().get(key); 

这段代码最终会访问配置文件,然后读取key-value对到Configuration中,我们在portal.properties中找到了portal.ctx的定义:

## 

## Portal Context 

    # 

    # Specify the path of the portal servlet context. This is needed because 

    # javax.servlet.ServletContext did not have access to the context path until 

    # Java EE 5. 

    # Set this property if you deploy the portal to another path besides root. 

    portal.ctx=/ 

所以portal.ctx=/

解析PATH_MAIN:

它在Portal接口中有定义:

public static final String PATH_MAIN = "/c"; 

所以综上所述,在PortalImpl构造器中的_pathMain = _pathContext + PATH_MAIN="/"+"/c"="//c"

它就是<%=redirect%>的值。

所以当index.jsp中DOM树加载完毕之后,它会去执行:

<body onload="javascript:location.replace('//c')">  

而对于location.replace(String)方法,它的作用是启动一个不可逆的重定向:参见下面这篇文章:

<a href="http://www.roseindia.net/javascript/javascript-location-replace.shtml">http://www.roseindia.net/javascript/javascript-location-replace.shtml</a>

所以我们现在知道,在DOM树加载完毕后,它吧请求发送到了http://localhost:8080/c 这个位置。

之后的步骤见下一篇博客

本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/905695,如需转载请自行联系原作者

继续阅读