eXo portal的请求处理机制

http://www.exoplatform.org/documents/exo-portal.site/portal.html

Let's describe how our Java Server Faces based portal works. This section gives an overview of the eXo portal achitecture, how we use JSF and the way the portal interacts with the portlet container. We focus on the request lifecycle which goes through the filter phase, the reconstitute request tree phase, the decode phase and finally, the render phase.

The eXo portal is composed of many portlet WARs and a master eXo portal WAR (several in case of multi portal instances). The eXo portal module is responsible for checking the security, decoding the request, loading the user configuration, building the jsf tree, and distpatching the request to the portlet container. When all the portlets located in the requested page are rendered, the portal returns an aggregated page to the client.

Portal initialization

When the web server is started or the eXo web arvchive (WAR) is deployed, the PortalContextListener (You can find the configuration of this listener in web.xml) will catch the start event and run the checking code for eXo tables, the default groups and the default users. If the anonymous and admin users are missing, the listener will look up the organization service, to create the missing user.

Portlet Initialization

When the webserver is started or a portlet war is dropped into the portlet deployed directory, the PortletApplicationListener (You can find the configuration of this listener in portlet.war/WEB-INF/web.xml or default-web.xml) will catch the start event, it will lookup for the portlet container service and register the application with the portlet container if a portlet.xml file is present.

Request processing

After the server is started and that all the initialization has been done. The portal is ready to receive the first request. There is a very simple rule to handle the request : any dynamic request must go though the portal and be treated by the filter , the jsf servlet controller and the portlet container. For a static resource request, such as an image file, the request can be handled by the default servlet of portal or the default servlet of the portlet; only depending on the context path of the request.

Filter phase

When a request is sent to the portal, it will be first handle by either a PublicRequestFilter or a PrivateRequestFilter (you can find the configuration of those 2 filters in exo/WEB-INF/web.xml) depending on the url type. We currently define 2 types of url, public and private. The public url has the form /portal/faces/publicÉ and the private url has the form /portal/faces/privateÉ Both public and private paths you saw in 2 url are virtual paths and they are defined in the web.xml. The role of filter is to check the Owner Context. If the owner context does not match with the current user context or no user context exists in the session, the filter will destroy the jsf tree in the session, reload the user context according the request, and store the user context in the session.

Reconstitute JSF tree phase

After the filter phase, the request is forwarded to the FacesServlet. The FacesServlet will get the Lifecycle instance and will execute the faces lifecycle. One important phase in the faces lifecycle is the process reconstitute part. It will check for a tree id in the session - id associated with the request tree - and will reconstruct the component tree if the two trees are not the same. With exo, you always make the request to the same URL so the jsf tree is always cached in session. The JSF tree is destroyed and reconstructed only when the request user context does not match with the one in the session (done in the filter phase). Note that the exo jsf tree is constructed based on the owner-config.xml, owner-navigation.xml and owner-pages.xml configuration file of the user, basically you will have a ui component tree that reflects those xml files.

JSF Decode phase

The next phase of the faces cycle is the decode phase or apply request phase. In this phase, the JSF implementation iterates over the components in the component tree and calls each component's decode() method. That method extracts information from the request and stores it in the component.

The UIPorlet decode() will do 3 main tasks : (1) Check for the "change mode" event : if the event is detected and the request component id matches the current UIPorlet component id, it will raise an event and will delegate it to the PortletActionListnenter class. The listener will reset the mode in the UIPortlet Component.

(2) Check for the "change window" state event: if the event is detected and that the request component id matches the current UIPorlet component id, it will raise an event and will delegate it to the PortletActionListnenter class. The listener will reset the window state in the UIPortlet Component.

(3) Check for the portlet action type: According the portlet spec, we have 2 types of action : one is the action type and the other one is the render type. If the type is action , the processAction(..) method of the portlet will be called and then the render(....) method is called. If the type is render, only the render(..) method is called. It is mandatory that the processAction(..) has to be called before any render(..) method is called. The reason for this requirement is because a portlet can process an action and send a message to another portlet. Indeed, it would not make any sense if the render(...) method of the other portlet has already been called. Once again we can see how JSF technology fits very well with portlet technology, by defining many process phase. This way, it will make sure that each processAction(..) of each portlet will be called first and each render(..) method of each portlet will be called in the render phase

JSF Render phase

Finally the Render phase creates the html page by calling the methods encodeBegin(..) encodeChildren(..) and encodeEnd(..) of the root component. The parent UIComponent will control the render phase of its children. With the eXo portal jsf tree, the root component is UIPortal component. In UI Portlet Renderer, since the UIPortlet has no children, only encodeBegin(..) is required to be called. We create the RenderInput object, it contains all the information of the request, and delegates it to the portlet container. The portlet container will then invoke the method render(..) and return an OutputObject. Then the portal renders the portlet header and the portlet body using the content returned by the portlet container in the Output object. Note that in the portal page you have many portlets but each request only targets one portlet. Therefore, the parameter map sent to the container is cached as a parameter map in the associated UIPortlet object. Only the portlet you send request to use HttpServletRequest parameter map or a parameter map produced by the processAction() method. All of those steps are processed in the decode phase.

本项目是一个基于SSM(Spring+SpringMVC+MyBatis)框架和Vue.js前端技术的大学生第二课堂系统,旨在为大学生提供一个便捷、高效的学习和实践平台。项目包含了完整的数据库设计、后端Java代码实现以及前端Vue.js页面展示,适合计算机相关专业的毕设学生和需要进行项目实战练习的Java学习者。 在功能方面,系统主要实现了以下几个模块:用户管理、课程管理、活动管理、成绩管理和通知公告。用户管理模块支持学生和教师的注册、登录及权限管理;课程管理模块允许教师上传课程资料、设置课程时间,并由学生进行选课;活动管理模块提供了活动发布、报名和签到功能,鼓励学生参与课外实践活动;成绩管理模块则用于记录和查询学生的课程成绩和活动参与情况;通知公告模块则实时发布学校或班级的最新通知和公告。 技术实现上,后端采用SSM框架进行开发,Spring负责业务逻辑层,SpringMVC处理Web请求,MyBatis进行数据库操作,确保了系统的稳定性和扩展性。前端则使用Vue.js框架,结合Axios进行数据请求,实现了前后端分离,提升了用户体验和开发效率。 该项目不仅提供了完整的源代码和相关文档,还包括了详细的数据库设计文档和项目部署指南,为学习和实践提供了便利。对于基础较好的学习者,可以根据自己的需求在此基础上进行功能扩展和优化,进一步提升自己的技术水平和项目实战能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值