REST API的users.getInfo,user.isAppAdded等method, 如何在开放平台的服务器端dispatch到对应的class或module来进行处理? 以下是一利用java的反射机制的简单示例代码,仅作抛砖引玉。
package com.xxx.api.web.restlet; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.StringTokenizer; import org.restlet.data.MediaType; import org.restlet.data.Response; import org.restlet.data.Status; import org.restlet.resource.Resource; /** * * @author Yang Hongfen */ public class APIResoure extends Resource { private MemberInfoService memberInfoService; private PlugAppService plugAppService; private TokenDataStoreAccess tokenAccess; @SuppressWarnings("unused") private com.xxx.api.service.users.Service usersService; @SuppressWarnings("unused") private com.xxx.api.service.friends.Service friendsService; @Override public boolean allowPost() { return true; } /** * Handle POST requests: */ @Override public void handlePost() { Map<String, Object> attributes = getRequest().getAttributes(); String methodStr = (String) attributes.get("method"); String api_key = (String) attributes.get("api_key"); String auth_token = (String) attributes.get("auth_token"); String api_sig = (String) attributes.get("api_sig"); String call_id_str = (String) attributes.get("call_id"); attributes.remove("api_sig"); if (methodStr == null || methodStr.length() == 0 || api_sig == null || api_sig.length() == 0 || call_id_str == null || call_id_str.length() == 0) { ErrorUtil.generateErrorRepresentation( Status.CLIENT_ERROR_BAD_REQUEST, ErrorCode.PARAMETER_MISSING_OR_INVALID, getResponse()); return; } Float call_id = Float.valueOf(call_id_str); // 根据API_KEY获取相应的APP应用 PlugApp plugApp = plugAppService.getByAPIKey(api_key); if (plugApp == null) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.INVALID_API_KEY, getResponse()); return; } if (plugApp.getAudit()!=1 || plugApp.getIsPublished()!=1 || plugApp.getIsClosed()!=0){ ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.SERVICE_UNAVAILABLE, getResponse()); return; } String secret = plugApp.getSecret(); if (!api_sig.equals(APIUtils.calculateSignature(attributes, secret))) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.INCORRECT_SIGNATURE, getResponse()); return; } if (methodStr.equals("auth.createToken")) { String ticket = (String) attributes.get("ticket"); String uid = (String) attributes.get("uid"); Integer memberId = Integer.parseInt(uid); MemberVo vo = null; try { vo = memberInfoService.findMemberInfoById(memberId); } catch (Exception e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.SERVICE_UNAVAILABLE, getResponse()); return; } if (vo == null) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.INVALID_USER_ID, getResponse()); return; } if( !plugAppService.isAppUser(plugApp.getId(), memberId)){ //todo } // todo: 判断ticket和memberId的登录合法性: ResultInfo<KeyEntry> token = tokenAccess.generateToken(plugApp, ticket, memberId); RepresentationUtil.createTokenResult(token.getEntity().getAuth_token(), vo, getResponse()); return; } // 其他的需要验证token的method的处理: ResultInfo<KeyEntry> entry = tokenAccess.getEntry(auth_token,call_id); if (entry.getCode() != 0) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, entry.getMessage(), getResponse()); return; } // Dispatch and Process: attributes.put("curr_uid", entry.getEntity().getMemberId()); attributes.put("app_id", entry.getEntity().getApp_id()); StringTokenizer st = new StringTokenizer(methodStr, "."); String packageName = st.nextToken(); String methodName = st.nextToken(); try { Object serviceObj = this.getClass().getField(packageName + "Service").get( this); Method method = serviceObj.getClass().getMethod(methodName); method.invoke(serviceObj, attributes); } catch (NoSuchFieldException e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.METHOD_NOT_FOUND, getResponse()); return; } catch (IllegalArgumentException e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.UNKNOWN_ERROR, getResponse()); } catch (SecurityException e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.UNKNOWN_ERROR, getResponse()); } catch (IllegalAccessException e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.UNKNOWN_ERROR, getResponse()); } catch (NoSuchMethodException e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.METHOD_NOT_FOUND, getResponse()); return; } catch (InvocationTargetException e) { ErrorUtil.generateErrorRepresentation(Status.SUCCESS_OK, ErrorCode.UNKNOWN_ERROR, getResponse()); } return; } }
TokenDataStoreAccess.java:
/** * * @author Yang Hongfen */ public interface TokenDataStoreAccess { ResultInfo<KeyEntry> getEntry(String token,Float call_id); ResultInfo<KeyEntry> generateToken(PlugApp plugApp,String ticket,Integer member_id); }
TokenDataStoreAccessImpl.java
package com.xxx.api.auth; import java.util.Date; import java.util.UUID; import com.xxx.api.constants.ErrorCode; import com.xxx.cache.CacheClient; import com.xxx.domain.my.PlugApp; import com.xxx.service.my.PlugAppService; import com.xxx.util.ResultInfo; /** * * @author Yang Hongfen */ public class TokenDataStoreAccessImpl implements TokenDataStoreAccess{ private CacheClient cacheClient; public ResultInfo<KeyEntry> getEntry(String token,Float call_id){ ResultInfo<KeyEntry> ri = new ResultInfo<KeyEntry>(); if( cacheClient.keyExists(token) ){ KeyEntry entry = (KeyEntry)cacheClient.get(token); if( entry.isTimeOut() ){ cacheClient.delete(token); ri.setCode(-1); ri.setMessage(ErrorCode.INVALID_AUTH_TOKEN); return ri; } if(call_id<=entry.getCall_id()){ ri.setCode(-1); ri.setMessage(ErrorCode.INVALID_CALL_ID); return ri; } entry.call_id = call_id; entry.accessTime = new Date(); cacheClient.addOrReplace(token, entry); ri.setCode(0); ri.setEntity(entry); return ri; } else{ ri.setCode(-1); ri.setMessage(ErrorCode.INVALID_AUTH_TOKEN); return ri; } } public ResultInfo<KeyEntry> generateToken(PlugApp plugApp,String ticket,Integer member_id){ ResultInfo<KeyEntry> ri = new ResultInfo<KeyEntry>(); KeyEntry entry = new KeyEntry(); entry.api_key = plugApp.getApiKey(); entry.ticket = ticket; entry.app_id = plugApp.getId(); entry.callbackUrl = plugApp.getCallBackUrl(); entry.memberId = member_id; entry.auth_token = UUID.randomUUID().toString(); entry.accessTime = new Date(); entry.call_id = new Float(0); cacheClient.add(entry.getAuth_token(), entry); ri.setCode(1); ri.setMessage("成功!"); ri.setEntity(entry); return ri; } }