本文讲述了J2EE+Flex的一些开发心得。作者一直是搞J2EE的,使用了blazeds,Flex通过RemoteObject调用Java的后台方法。这样的一个最大的好处就是不再需要struts这样之类的框架了,可以直接使用spring中的bean。
AD:
最近学习了下Flex,我一直是搞J2EE的。所以想整合试着开发,J2EE+Flex在网上查了些资料,有好几种方法。我这里使用的是blazeds,Flex通过RemoteObject调用Java的后台方法。我个人觉得这样的一个最大的好处就是不再需要struts这样之类的框架了,可以直接使用spring中的bean。要使用spring就必须先说下spring的整合问题,其实这个网上也有,只要就是一个SpringFactory类,这个类要实现FlexFactory接口,然后在WEB-INF/flex/services-config.xml中注册改factory。代码如下:
- < factories>
- < factory id="springContext" class="com.wangmeng.flex.SpringFactory">< /FACTORY>
- < /FACTORIES>
这样配置好以后在WEB-INF/flex/remote-config.xml中只要把factory的名字写成和上面配置对应的名字如:springContext,source的值配置为spring中bean的id就可以了。例如:
- < destination id="userLoginService">
- < properties>
- < factory>springContext< /FACTORY>
- userLoginService< /SOURCE>
- < /PROPERTIES>
- < /DESTINATION>
具体SpringFactory类的源代码网上也有。
下面我说下我构思的控制菜单及权限的方法:首先要控制肯定要有用户登录的环节,这里具体怎么实现都可以,当时登陆后要将用户的信息保存在session中,一遍在检查权限是使用。获取request,session都是通过flex.messaging.FlexContext提供的静态方法
首先说菜单的控制,当用户打开首页,客户端远程调用加载菜单信息,当然这是没有登陆,只有一些公开的菜单可以看见,用户登录后可以再重新加载菜单,这是系统会根据用户的特权等级决定要返回的菜单列表(这里菜单的返回的数据来源你可以自己决定,可以放在数据库里也可以是其他的)。
当然,只是这样控制肯定不够安全,那就是后面要说的对用spring中bean调用的控制:
要控制spring中的bean不被越权调用当然要从前面的SpringFactory类着手啦,我们需要在每次调用bean之前通过bean的名字检查该用户是否有权调用,如果有权调用就返回该bean,如果没有权限就抛出一个没有权限的ServiceException类。还是具体看下我的实现代码吧,也许不是很优美,但是功能大致都实现了。
- package com.wangmeng.flex;
- import java.util.HashMap;
- import java.util.List;
- import javax.servlet.http.HttpSession;
- import org.springframework.context.ApplicationContext;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.NoSuchBeanDefinitionException;
- import com.wangmeng.web.data.SysPrivilege;
- import com.wangmeng.web.data.User;
- import com.wangmeng.web.service.privilege.PrivilegeService;
- import flex.messaging.FactoryInstance;
- import flex.messaging.FlexFactory;
- import flex.messaging.config.ConfigMap;
- import flex.messaging.services.ServiceException;
- public class SpringFactory implements FlexFactory {
- private static final String SOURCE = "source";
- private static HashMap beanMap = new HashMap();//存放权限检查项
- //在factory初始化是装在权限信息
- public void initialize(String id, ConfigMap configMap) {
- ApplicationContext appContext = WebApplicationContextUtils
- .getWebApplicationContext(flex.messaging.FlexContext
- .getServletConfig().getServletContext());
- PrivilegeService priviService = (PrivilegeService) appContext
- .getBean("sysPrivilegeService");
- List priviList = priviService.listAll();
- for (Object obj : priviList) {
- SysPrivilege privi = (SysPrivilege) obj;
- String name = privi.getServiceName();
- beanMap.put(name, privi);
- }
- }
- public FactoryInstance createFactoryInstance(String id, ConfigMap properties) {
- SpringFactoryInstance instance = new SpringFactoryInstance(this, id,
- properties);
- instance.setSource(properties.getPropertyAsString(SOURCE, instance
- .getId()));
- return instance;
- }
- public Object lookup(FactoryInstance inst) {
- SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
- return factoryInstance.lookup();
- }
- static class SpringFactoryInstance extends FactoryInstance {
- SpringFactoryInstance(SpringFactory factory, String id,
- ConfigMap properties) {
- super(factory, id, properties);
- }
- public String toString() {
- return "SpringFactory instance for id=" + getId() + " source="
- + getSource() + " scope=" + getScope();
- }
- //在每次查找spring bean之前检查权限。
- public Object lookup() {
- String beanName = getSource();
- SysPrivilege privi = (SysPrivilege) beanMap.get(beanName);
- boolean hasRight = false;
- if (privi==null||privi.getLevel() <= 0) {
- hasRight = true;
- } else {
- HttpSession session = flex.messaging.FlexContext
- .getHttpRequest().getSession();
- User user = (User) session.getAttribute("user");
- if (user != null && user.getPrivilege() >= privi.getLevel()) {
- hasRight = true;
- } else {
- hasRight = false;
- }
- }
- if (hasRight) {
- ApplicationContext appContext = WebApplicationContextUtils
- .getWebApplicationContext(flex.messaging.FlexContext
- .getServletConfig().getServletContext());
- try {
- return appContext.getBean(beanName);
- } catch (NoSuchBeanDefinitionException nexc) {
- ServiceException e = new ServiceException();
- String msg = "Spring service named '" + beanName
- + "' does not exist.";
- e.setMessage(msg);
- e.setRootCause(nexc);
- e.setDetails(msg);
- e.setCode("Server.Processing");
- throw e;
- } catch (BeansException bexc) {
- ServiceException e = new ServiceException();
- String msg = "Unable to create Spring service named '"
- + beanName + "' ";
- e.setMessage(msg);
- e.setRootCause(bexc);
- e.setDetails(msg);
- e.setCode("Server.Processing");
- throw e;
- }
- }else{
- ServiceException e = new ServiceException();
- String msg = "你没有足够的权限调用'"
- + beanName + "' ";
- e.setMessage(msg);
- e.setRootCause(null);
- e.setDetails(msg);
- e.setCode("Server.Processing");
- throw e;
- }
- }
- }
- }
代码不是很难,稍微看下我想应该没有问题。这就是我的构思,如果真的要应用还有许多细节要考虑,至少一个大致的框架完成了。