J2EE+Flex的菜單及權(quán)限控制實(shí)踐
最近學(xué)習(xí)了下Flex,我一直是搞J2EE的。所以想整合試著開發(fā),J2EE+Flex在網(wǎng)上查了些資料,有好幾種方法。我這里使用的是blazeds,F(xiàn)lex通過RemoteObject調(diào)用Java的后臺(tái)方法。我個(gè)人覺得這樣的一個(gè)***的好處就是不再需要struts這樣之類的框架了,可以直接使用spring中的bean。要使用spring就必須先說下spring的整合問題,其實(shí)這個(gè)網(wǎng)上也有,只要就是一個(gè)SpringFactory類,這個(gè)類要實(shí)現(xiàn)FlexFactory接口,然后在WEB-INF/flex/services-config.xml中注冊(cè)改factory。代碼如下:
- < factories>
- < factory id="springContext" class="com.wangmeng.flex.SpringFactory">< /FACTORY>
- < /FACTORIES>
這樣配置好以后在WEB-INF/flex/remote-config.xml中只要把factory的名字寫成和上面配置對(duì)應(yīng)的名字如:springContext,source的值配置為spring中bean的id就可以了。例如:
- < destination id="userLoginService">
- < properties>
- < factory>springContext< /FACTORY>
- userLoginService< /SOURCE>
- < /PROPERTIES>
- < /DESTINATION>
具體SpringFactory類的源代碼網(wǎng)上也有。
下面我說下我構(gòu)思的控制菜單及權(quán)限的方法:首先要控制肯定要有用戶登錄的環(huán)節(jié),這里具體怎么實(shí)現(xiàn)都可以,當(dāng)時(shí)登陸后要將用戶的信息保存在session中,一遍在檢查權(quán)限是使用。獲取request,session都是通過flex.messaging.FlexContext提供的靜態(tài)方法
首先說菜單的控制,當(dāng)用戶打開首頁,客戶端遠(yuǎn)程調(diào)用加載菜單信息,當(dāng)然這是沒有登陸,只有一些公開的菜單可以看見,用戶登錄后可以再重新加載菜單,這是系統(tǒng)會(huì)根據(jù)用戶的特權(quán)等級(jí)決定要返回的菜單列表(這里菜單的返回的數(shù)據(jù)來源你可以自己決定,可以放在數(shù)據(jù)庫里也可以是其他的)。
當(dāng)然,只是這樣控制肯定不夠安全,那就是后面要說的對(duì)用spring中bean調(diào)用的控制:
要控制spring中的bean不被越權(quán)調(diào)用當(dāng)然要從前面的SpringFactory類著手啦,我們需要在每次調(diào)用bean之前通過bean的名字檢查該用戶是否有權(quán)調(diào)用,如果有權(quán)調(diào)用就返回該bean,如果沒有權(quán)限就拋出一個(gè)沒有權(quán)限的ServiceException類。還是具體看下我的實(shí)現(xiàn)代碼吧,也許不是很優(yōu)美,但是功能大致都實(shí)現(xiàn)了。
- 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();//存放權(quán)限檢查項(xiàng)
- //在factory初始化是裝在權(quán)限信息
- 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之前檢查權(quán)限。
- 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 = "你沒有足夠的權(quán)限調(diào)用'"
- + beanName + "' ";
- e.setMessage(msg);
- e.setRootCause(null);
- e.setDetails(msg);
- e.setCode("Server.Processing");
- throw e;
- }
- }
- }
- }
代碼不是很難,稍微看下我想應(yīng)該沒有問題。這就是我的構(gòu)思,如果真的要應(yīng)用還有許多細(xì)節(jié)要考慮,至少一個(gè)大致的框架完成了。
【編輯推薦】