文章来源:http://flexhome.iteye.com/blog/157144
Flex Remote Object可以是POJO,JavaBean或是EJB。在面向服务的架构中(Service Oriented Architecture),我们可以用Remote Object来作为Service Facade,利用应用服务器提供的persistent service来储存状态信息。
Flex既可以提供stateful或stateless的remote object, 另外还有session servlet让mxml获取/和储存session中的内容。这一切听上去都很完美,但是有一个问题,Flex Remote Object本身是无法获得任何有关Running Context的信息,也就是说,你无法从你的 Remote Object 中获得 HttpSession, HttpRequest 和 ServletContext。 所谓的 Flex Session servlet只是让MXML获得session的内容,而不是直接让Remote Object获得session。
Remote Object为什么需要获得HttpRequest, HttpSession?
既然Flex提供了stateful的remote object为什么还要让remote object获得Running Context呢?问题在于Flex中的stateful是基于应用服务器的http session,而且你无法控制AMFGateway建立remote object的过程。打个简单的比方,我们知道一般的应用服务器中,session的时限只有20分钟,而在很多系统的登陆过程中却有选择保持登陆几个月的选项。
其具体实现上就是利用cookie来储存id和password hash,通过控制cookie的存活时间来实现的。而在服务器端,一旦session过期了,则可以从cookie中获得id和password hash重新登陆一遍,从而达到自动认证用户的目的。
如果你的Remote Object无法获得 HttpServletRequest, HttpSession,你就无法实现上述的情况。另外,对于小型的应用来说,直接在Remote object中获得servlet context并利用它来储存/获得共享的资源,可以大大降低开发的复杂程度。
解决方案
要让Remote Object获得HttpSession,HttpRequest和ServletContext并不是一件容易的事情。这里提供了我的一种方法,供大家参考。希望能抛砖引玉,让大家提出更好,更有效的方案。
这个方法的基本思路是利用JAVA提供的 ThreadLocal Object。当服务器接收到一个HTTP请求后,这个请求的整个处理过程是运行在同一个线程中的。
每个HTTP请求的处理会都运行在各自独立的线程中。而在Flex中,所有AMF Remote Object 的请求都需要通过 AMF Gateway Servlet,而Remote Object 的建立和调用恰恰就是运行在这个HTTP请求的线程中。
有了这个原则,我们就可以建立一个Context Object,每当请求建立的时候,就可以把这个请求放入 Context 的 ThreadLocal 中,而当 Remote Object 被AMF Gateway Servlet调用的时候,就可以通过访问 Context 的ThreadLoca l来获得其所对应的那个请求。
而截获发送到AMF Gateway的请求则可以通过Servlet Filter来实现。废话不说了,看代码吧! 1. 添加以下内容到WEB-INF/web.xml中
<filter>
<filter-name>AMFSessionFilter </filter-name>
<filter-class>com.netop.forum.servlets.AMFSessionFilter </filter-class>
<filter>
<filter-mapping>
<filter-name>AMFSessionFilter </filter-name>
<servlet-name>AMFGatewayServlet </servlet-name>
<filter-mapping>
2. AMFSessionFilter的代码
/*
* Created on 1/07/2004
*/
package com.netop.forum.servlets;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Zombie
* @version 0.5
*/
public class AMFSessionFilter implements Filter
{
private static Log log = LogFactory.getLog(AMFSessionFilter.class);
public void init(FilterConfig config)
{
log.info("Init AMFSessionFilter filter");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException,IOException
{
AMFContext.setCurrentContext((HttpServletRequest)request, (HttpServletResponse)response);
chain.doFilter(request,response);
}
public void destroy()
{
log.info("Destory AMFSessionFilter filter");
}
}
3. AMFContext的代码
/*
* Created on 1/07/2004
*/
package com.netop.forum.servlets;
import javax.servlet.*;
import javax.servlet.http.*;
import com.netop.forum.business.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Zombie
* @version 0.5
*/
public class AMFContext
{
/**
* Context Attribute key for the connection the factory
*/
public final static String CONNECTION_FACTORY_KEY = "sqlMapFactory";
/**
* The log
*/
private static Log log = LogFactory.getLog(AMFContext.class);
/**
* ThreadLocal object for storing object in current thread.
*/
private static ThreadLocal tl = new ThreadLocal();
/**
* Set current context
*
* @param request The HttpRequest object
* @param response The HttpResponses object
*/
static public void setCurrentContext(HttpServletRequest request, HttpServletResponse response)
{
AMFContext c = getCurrentContext();
if (c == null)
{
c = new AMFContext(request,response);
tl.set(c);
}
else
{
c.setRequest(request);
c.setResponse(response);
}
}
/**
* Get current context value
* @return The current context
*/
static public AMFContext getCurrentContext()
{
return (AMFContext)tl.get();
}
//----------------------------------------------------------
//
// Class members
//
//----------------------------------------------------------
/**
* The http request object. The lifecycle of the request object is defined as the request
* scope. It may be reused in another incoming connection, so dont use it in another thread.
*/
private HttpServletRequest request;
/**
* The http response object. The lifecycle of the response object is defined as the request
* scope. Dont use it in another thread. Also dont write output to the response when it is
* used in the context, but you may get or set some response header when it is safe.
*/
private HttpServletResponse response;
/**
* The constructor is private, to get an instance of the AMFContext, please use
* getCurrentContext() method.
*
* @param request
* @param response
*/
private AMFContext (HttpServletRequest request, HttpServletResponse response)
{
this.request = request;
this.response = response;
}
/**
* Get request object
*
* @return Http request object
*/
public HttpServletRequest getRequest()
{
return request;
}
/**
* Set request object
*
* @param Http request object
*/
public void setRequest(HttpServletRequest request)
{
this.request = request;
}
/**
* Get response object
*
* @return Http response object
*/
public HttpServletResponse getResponse()
{
return response;
}
/**
* Set response object
*
* @param response Http response object
*/
public void setResponse(HttpServletResponse response)
{
this.response = response;
}
/**
* Get the servlet context
* @return
*/
public ServletContext getServletContext()
{
HttpSession session = this.getSession();
return session.getServletContext();
}
/**
* Get the current running session
* @return
*/
public HttpSession getSession()
{
return request.getSession();
}
/**
* Get an object stored in the session.
*
* @param attr Attribute Name
* @return The value stored under the attribute name.
*/
public Object getSessionAttribute(String attr)
{
HttpSession session = this.getSession();
return session.getAttribute(attr);
}
/**
* Store an object in the session.
*
* @param attr Attribute Name
* @param value The value.
*/
public void setSessionAttribute(String attr, Object value)
{
HttpSession session = this.getSession();
session.setAttribute(attr, value);
}
/**
* Get an object stored in the servlet context.
*
* @param attr Attribute Name
* @return The value stored under the attribute name.
*/
public Object getContextAttribute(String attr)
{
ServletContext sc = this.getServletContext();
return sc.getAttribute(attr);
}
/**
* Store an object in the servlet context.
*
* @param attr Attribute Name
* @param value The value.
*/
public void setContextAttribute(String attr, Object value)
{
ServletContext sc = this.getServletContext();
sc.setAttribute(attr,value);
}
/**
* Get an object stored in the current request.
*
* @param attr Attribute Name
* @return The value stored under the attribute name.
*/
public Object getRequestAttribute(String attr)
{
return request.getAttribute(attr);
}
/**
* Store an object in the current request.
*
* @param attr Attribute Name
* @param value The value.
*/
public void setRequestAttribute(String attr, Object value)
{
request.setAttribute(attr,value);
}
/**
* Get the connection factory from the servlet context. The connection factory is in the
* application scope.
*
* @return The connection factory for creating sqlMap objects.
*/
public ConnectionFactory getConnectionFactory()
{
ConnectionFactory factory =(ConnectionFactory)this.getContextAttribute(CONNECTION_FACTORY_KEY);
if (factory == null)
{
try
{
factory = new ConnectionFactory();
// factory is lazy instantiated, so we need to invoke it once to make sure it is ok.
factory.getSqlMap();
this.setContextAttribute(CONNECTION_FACTORY_KEY, factory);
}
catch (Throwable e)
{
log.fatal("Can not create connection factory: "+e.getMessage(), e);
}
}
return factory;
}
}
4. 如何在remote object中使用AMFContext
class YouRemoteService
{
public void serviceMethod()
{
AMFContext context = AMFContext.getCurrentContext();
HttpSession = context.getSession();
ServletContext = context.getServletContext();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
context.setSessionAttribute("attr","value");
context.setContextAttribute("attr","value");
}
}
分享到:
相关推荐
一旦有了`HttpSession`对象,就可以使用`setAttribute(String name, Object value)`方法来存储数据,使用`getAttribute(String name)`来检索数据。这里的`name`是键,`value`是对应的值。如果需要移除某个属性,可以...
标题中的“httpSession”指的是HTTP...总的来说,httpSession是Web开发中不可或缺的一部分,理解其原理和正确使用方式对于构建健壮的、高可用的应用程序至关重要。通过学习和实践,我们可以更好地掌握这一核心技术。
* 可以在新的页面中使用 Thymeleaf 语法来读取 HttpSession 中的数据 缺点: * 需要使用 HttpSession 来存放数据 * 需要在控制器中实现数据存放和重定向 应用场景: * 在表单提交后重定向到新的页面 * 在 Ajax ...
3. 获取HttpSession:在WebSocket消息处理方法中,我们可以利用`@Principal`注解获取当前登录用户的信息,然后通过`RequestContextHolder`获取`ServletRequestAttributes`,进一步获取HttpSession。 4. 客户端配置...
最后,在WebSocket服务器端的方法中,可以通过以下方式获取`HttpSession`: ```java @ServerEndpoint(value = "/server/", configurator = GetHttpSessionConfigurator.class) public class WebSocketServer { @On...
在本文中,我们将深入探讨如何使用Java编程语言和HttpSession接口来实现一个简单的验证码登录系统。验证码(CAPTCHA)是一种防止恶意机器人或自动化程序非法访问网站的安全机制,它要求用户输入图片上显示的一组随机...
3. **设置和获取属性**:`HttpSession`提供了`setAttribute(String name, Object value)`方法来存储键值对,以及`getAttribute(String name)`来获取存储的属性。在这个例子中,我们使用`setAttribute("history", ...
### JSP中Session使用方法详解 #### 一、引言 在Web开发中,会话管理是一项非常重要的功能,特别是对于需要保持用户状态的应用程序来说更是如此。在Java Web开发中,`HttpSession`接口提供了会话管理的功能,它是...
在WebSphereApplicationServerV7集群环境中管理HTTPsession.pdf
- `void setAttribute(String name, Object value)`: 将对象 `value` 保存到 `HttpSession` 对象中,并为其指定引用名称 `name`。 - `Object getAttribute(String name)`: 根据 `name` 获取保存在 `HttpSession` ...
- `setAttribute(String name, Object value)`:在Session中存储键值对。 - `getAttribute(String name)`:获取指定键的值。 - `removeAttribute(String name)`:删除指定键的属性。 **5. Session生命周期** - **...
在本文中,我们学习了 Java 使用 WebSocket 并获取 HttpSession 的方法。我们了解了 WebSocket 的基本概念、Java 中的 WebSocket 实现、获取 HttpSession 的方法、Spring Boot 中的 WebSocket 实现、配置 WebSocket ...
总的来说,本章节涵盖了状态管理的基本概念,Cookie的创建、查询、修改和生命周期,以及HttpSession的使用。学习者应该掌握这些内容,以便在实际的Web应用开发中有效地处理客户端和服务器之间的状态保持。
servlet-api.jar 适用于import javax.servlet.http.HttpSession;异常 直接下载后直接导入 即可,
在 DWR 中取得 Session 等信息可以使用两种方法:使用 DWR 的 API 或者在 Java 服务方法中定义参数。后者是推荐的做法,因为它更简洁、更易于维护。无论使用哪种方法,都是为了获取用户信息,以便更好地实现业务逻辑...
描述中的"利用session完成设计"意味着我们需要使用HttpSession接口来存储用户的状态信息。在游戏过程中,服务器需要记住用户的猜测次数,而session正是为此目的而设计的。当用户发送一个请求时,我们可以在session中...
在提供的压缩包文件列表中,"GetMac.dll"可能是一个用来获取机器MAC地址的动态链接库,这在某些情况下可能会与确定物理位置有关,但并不是直接获取物理URL的方法。"readme.htm"可能是关于如何使用这些组件的说明,...
通过调用`session.setAttribute()`方法,我们可以将对象绑定到会话中,然后在后续的请求中使用`session.getAttribute()`获取。会话通常基于一个唯一的ID(JSESSIONID),这个ID由服务器分配,并通过cookie或URL重写...
通常,如果只需要在Action中简单地使用Response对象,直接实现`ServletResponseAware`接口是最简洁的方法。而如果需要更复杂的请求处理,可以考虑使用ActionContext或者ServletActionContext。同时,使用...
Cairngorm 框架是 Adobe Flex 开发中的一个著名模型-视图-控制器(MVC)架构,它提供了一种结构化的方法来组织和管理应用程序代码,从而提高开发效率和代码可维护性。该框架的核心思想是将应用程序的不同部分——...