package com.googlecode.jsonrpc4j.spring; import com.fasterxml.jackson.databind.ObjectMapper; import com.googlecode.jsonrpc4j.JsonRpcClient.RequestListener; import com.googlecode.jsonrpc4j.JsonRpcHttpClient; import com.googlecode.jsonrpc4j.ReflectionUtil; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.remoting.support.UrlBasedRemoteAccessor; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; /** * {@link FactoryBean} for creating a {@link UrlBasedRemoteAccessor} * (aka consumer) for accessing an HTTP based JSON-RPC service. */ @SuppressWarnings("unused") public class JsonProxyFactoryBean extends UrlBasedRemoteAccessor implements MethodInterceptor, InitializingBean, FactoryBean<Object>, ApplicationContextAware { private Object proxyObject = null; private RequestListener requestListener = null; private ObjectMapper objectMapper = null; private JsonRpcHttpClient jsonRpcHttpClient = null; private Map<String, String> extraHttpHeaders = new HashMap<>(); private String contentType; private SSLContext sslContext = null; private HostnameVerifier hostNameVerifier = null; private ApplicationContext applicationContext; /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public void afterPropertiesSet() { super.afterPropertiesSet(); proxyObject = ProxyFactory.getProxy(getServiceInterface(), this); if (objectMapper == null && applicationContext != null && applicationContext.containsBean("objectMapper")) { objectMapper = (ObjectMapper) applicationContext.getBean("objectMapper"); } if (objectMapper == null && applicationContext != null) { try { objectMapper = BeanFactoryUtils.beanOfTypeIncludingAncestors(applicationContext, ObjectMapper.class); } catch (Exception e) { logger.debug(e); } } if (objectMapper == null) { objectMapper = new ObjectMapper(); } try { jsonRpcHttpClient = new JsonRpcHttpClient(objectMapper, new URL(getServiceUrl()), extraHttpHeaders); jsonRpcHttpClient.setRequestListener(requestListener); jsonRpcHttpClient.setSslContext(sslContext); jsonRpcHttpClient.setHostNameVerifier(hostNameVerifier); if (contentType != null) { jsonRpcHttpClient.setContentType(contentType); } } catch (MalformedURLException mue) { throw new RuntimeException(mue); } } /** * {@inheritDoc} */ @Override public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); if (method.getDeclaringClass() == Object.class && method.getName().equals("toString")) { return proxyObject.getClass().getName() + "@" + System.identityHashCode(proxyObject); } Type retType = (invocation.getMethod().getGenericReturnType() != null) ? invocation.getMethod().getGenericReturnType() : invocation.getMethod().getReturnType(); Object arguments = ReflectionUtil.parseArguments(invocation.getMethod(), invocation.getArguments()); return jsonRpcHttpClient.invoke(invocation.getMethod().getName(), arguments, retType, extraHttpHeaders); } /** * {@inheritDoc} */ @Override public Object getObject() { return proxyObject; } /** * {@inheritDoc} */ @Override public Class<?> getObjectType() { return getServiceInterface(); } /** * {@inheritDoc} */ @Override public boolean isSingleton() { return true; } /** * {@inheritDoc} */ @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } /** * @param objectMapper the objectMapper to set */ public void setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } /** * @param extraHttpHeaders the extraHttpHeaders to set */ public void setExtraHttpHeaders(Map<String, String> extraHttpHeaders) { this.extraHttpHeaders = extraHttpHeaders; } /** * @param requestListener the requestListener to set */ public void setRequestListener(RequestListener requestListener) { this.requestListener = requestListener; } /** * @param sslContext SSL context to pass to JsonRpcClient */ public void setSslContext(SSLContext sslContext) { this.sslContext = sslContext; } /** * @param hostNameVerifier the hostNameVerifier to pass to JsonRpcClient */ public void setHostNameVerifier(HostnameVerifier hostNameVerifier) { this.hostNameVerifier = hostNameVerifier; } /** * @param contentType the contentType to pass to JsonRpcClient */ public void setContentType(String contentType) { this.contentType = contentType; } }