/** * * Handles method invocations to the {@link HasRpcToken} interface * implemented by the service. Also handles Annotation of service with * {@link RpcTokenImplementation} * * @throws ClassNotFoundException * if base service interface class cannot be found if actual * implemented interface is Async * * @since 0.5 */ protected Object handleHasRpcToken(Object proxy, Method method, Object[] args) throws MethodNotSupportedException, NoSuchMethodException, ClassNotFoundException { if (HasRpcToken.class.getMethod("setRpcToken", RpcToken.class).equals( method)) { // Check if service has annotation defining the Token class and // that this token matches the specified class Class<?> srvcIntf = determineProxyServiceBaseInterface(proxy); if (srvcIntf != null) { RpcTokenImplementation rti = srvcIntf .getAnnotation(RpcTokenImplementation.class); // Replace $ in class name in order to handle inner classes if (rti != null && !args[0].getClass().getName().replace("$", ".") .equals(rti.value())) { throw new RpcTokenException("Incorrect Token Class. Got " + args[0].getClass().getName() + " but expected: " + rti.value()); } } this.token = (RpcToken) args[0]; return null; } else if (HasRpcToken.class.getMethod("getRpcToken").equals(method)) { return this.token; } else if (HasRpcToken.class.getMethod("setRpcTokenExceptionHandler", RpcTokenExceptionHandler.class).equals(method)) { this.rpcTokenExceptionHandler = (RpcTokenExceptionHandler) args[0]; return null; } else if (HasRpcToken.class.getMethod("setRpcTokenExceptionHandler", RpcTokenExceptionHandler.class).equals(method)) { return this.rpcTokenExceptionHandler; } throw new MethodNotSupportedException("Method: " + method.getName() + " in class: " + method.getDeclaringClass().getName() + " not defined for class: " + proxy.getClass().getName()); }
/** * Process a call originating from the given request. Uses the * {@link RPC#invokeAndEncodeResponse(Object, java.lang.reflect.Method, Object[])} * method to do the actual work. * <p> * Subclasses may optionally override this method to handle the payload in any * way they desire (by routing the request to a framework component, for * instance). The {@link HttpServletRequest} and {@link HttpServletResponse} * can be accessed via the {@link #getThreadLocalRequest()} and * {@link #getThreadLocalResponse()} methods. * </p> * This is public so that it can be unit tested easily without HTTP. * * @param payload the UTF-8 request payload * @return a string which encodes either the method's return, a checked * exception thrown by the method, or an * {@link IncompatibleRemoteServiceException} * @throws SerializationException if we cannot serialize the response * @throws UnexpectedException if the invocation throws a checked exception * that is not declared in the service method's signature * @throws RuntimeException if the service method throws an unchecked * exception (the exception will be the one thrown by the service) */ public String processCall(String payload) throws SerializationException { // First, check for possible XSRF situation checkPermutationStrongName(); try { RPCRequest rpcRequest = RPC.decodeRequest(payload, delegate.getClass(), this); onAfterRequestDeserialized(rpcRequest); return RPC.invokeAndEncodeResponse(delegate, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(), rpcRequest.getFlags()); } catch (IncompatibleRemoteServiceException ex) { log( "An IncompatibleRemoteServiceException was thrown while processing this call.", ex); return RPC.encodeResponseForFailure(null, ex); } catch (RpcTokenException tokenException) { log("An RpcTokenException was thrown while processing this call.", tokenException); return RPC.encodeResponseForFailure(null, tokenException); } }
@Override protected void checkRpcTokenType(RpcToken token) { if (!(token instanceof com.google.gwt.user.client.rpc.XsrfToken)) { throw new RpcTokenException("Invalid RpcToken type: expected 'com.google.gwt.user.client.rpc.XsrfToken' but got '" + token.getClass() + "'"); } }