Foren

how to integrate Spring's HTTP invoker Liferay6.0.5

thumbnail
Masroor Khan, geändert vor 12 Jahren.

how to integrate Spring's HTTP invoker Liferay6.0.5

Regular Member Beiträge: 124 Beitrittsdatum: 09.09.08 Neueste Beiträge
Hi,

I want to integrate Spring's HTTP invoker as a web service for liferay plugin portlet(service). It is available for existing liferay service. But i want to user for new service.How can i do that.


Regards,

Masroor Khan
thumbnail
Masroor Khan, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Regular Member Beiträge: 124 Beitrittsdatum: 09.09.08 Neueste Beiträge
Masroor Khan:
Hi,

I want to integrate Spring's HTTP invoker as a web service for liferay plugin portlet(service). It is available for existing liferay service. But i want to user for new service.How can i do that.


Regards,

Masroor Khan


Is is possible Sprig's Http ivoker for custom services

please reply


Regards,

Masroor Khan
thumbnail
Masroor Khan, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Regular Member Beiträge: 124 Beitrittsdatum: 09.09.08 Neueste Beiträge
Masroor Khan:
Hi,

I want to integrate Spring's HTTP invoker as a web service for liferay plugin portlet(service). It is available for existing liferay service. But i want to user for new service.How can i do that.


Regards,

Masroor Khan


Is is possible Spring Http Invoker for liferay custom services


please reply


Regards,

Masroor
thumbnail
Masroor Khan, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Regular Member Beiträge: 124 Beitrittsdatum: 09.09.08 Neueste Beiträge
Masroor Khan:
Hi,

I want to integrate Spring's HTTP invoker as a web service for liferay plugin portlet(service). It is available for existing liferay service. But i want to user for new service.How can i do that.


Regards,

Masroor Khan


Is is possible Spring Http Invoker for liferay custom services


please reply


Regards,

Masroor
thumbnail
jelmer kuperus, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Liferay Legend Beiträge: 1191 Beitrittsdatum: 10.03.10 Neueste Beiträge
Since you're so persistent and no one answered i gave it a shot. Yes you can do it, but it's not that simple emoticon

Here's what i did

in your-portlet/docroot/WEB-INF/liferay-plugin-package.properties add the following lines

portal-dependency-jars=\
    spring-web-servlet.jar,\
    spring-web.jar,\
    spring-core.jar,\
    spring-context.jar,\
    spring-context-support.jar,\
    spring-beans.jar,\
    spring-asm.jar,\
    spring-aop.jar,\
    spring-expression.jar,\
    asm.jar,\
    aopalliance.jar,\


Then create a web.xml file in your-portlet/docroot/WEB-INF/web.xml with the following contents :

<!--?xml version="1.0" encoding="UTF-8"?-->


<web-app>

    <servlet>
        <servlet-name>Spring Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/remoting-servlet.xml</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring Servlet</servlet-name>
        <url-pattern>/spring/*</url-pattern>
    </servlet-mapping>

</web-app>



add a file called your-portlet/docroot/WEB-INF/remoting-servlet.xml with the following content

<!--?xml version="1.0" encoding="UTF-8"?-->

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
        <property name="interceptors">
            <list>
                <bean class="org.searchworkings.news.SecurityInterceptor" />
            </list>
        </property>
    </bean>

	<bean name="/org_searchworkings_news_service_spring_NewsService-http" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
		<property name="service">
            <bean class="org.searchworkings.news.service.NewsServiceUtil" factory-method="getService" />
        </property>
		<property name="serviceInterface" value="org.searchworkings.news.service.NewsService" />
	</bean>
</beans>



Create the security interceptor you are wiring


package org.searchworkings.news;

import com.liferay.portal.model.Company;
import com.liferay.portal.model.User;
import com.liferay.portal.security.auth.PrincipalThreadLocal;
import com.liferay.portal.security.permission.PermissionChecker;
import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
import com.liferay.portal.security.permission.PermissionThreadLocal;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.util.PortalUtil;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author Jelmer Kuperus
 */
public class SecurityInterceptor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		List<company> companies = CompanyLocalServiceUtil.getCompanies();

		long idOfFirstCompany = companies.iterator().next().getCompanyId();

		long userId = PortalUtil.getBasicAuthUserId(request, idOfFirstCompany);

		if (userId == 0) {
			response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
			return false;
		}

		User user = UserLocalServiceUtil.getUser(userId);

		PrincipalThreadLocal.setName(userId);

		PermissionChecker permissionChecker = PermissionCheckerFactoryUtil.create(user, true);
		PermissionThreadLocal.setPermissionChecker(permissionChecker);

		return true;

	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
						   ModelAndView modelAndView) throws Exception {

        PrincipalThreadLocal.setName(null);
        PermissionThreadLocal.setPermissionChecker(null);
	}
}

</company>



Here's the client code i used to test :

import com.liferay.portal.kernel.configuration.Configuration;
import com.liferay.portal.kernel.configuration.ConfigurationFactory;
import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
import com.liferay.portal.kernel.configuration.Filter;
import org.apache.commons.codec.binary.Base64;
import org.searchworkings.news.service.NewsService;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Properties;

public class Main {

	public static void main(String[] args) throws Exception {

		ConfigurationFactoryUtil.setConfigurationFactory(new ConfigurationFactory() {
			@Override
			public Configuration getConfiguration(ClassLoader classLoader, String name) {
				return new Configuration() {
					@Override
					public void addProperties(Properties properties) {

					}

					@Override
					public boolean contains(String key) {
						return false;
					}

					@Override
					public String get(String key) {
						return null;
					}

					@Override
					public String get(String key, Filter filter) {
						return null;
					}

					@Override
					public String[] getArray(String key) {
						return new String[0];
					}

					@Override
					public String[] getArray(String key, Filter filter) {
						return new String[0];
					}

					@Override
					public Properties getProperties() {
						return new Properties();
					}

					@Override
					public Properties getProperties(String prefix, boolean removePrefix) {
						return new Properties();
					}

					@Override
					public void removeProperties(Properties properties) {

					}

					@Override
					public void set(String key, String value) {

					}
				};
			}
		});


		HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
		factory.setServiceUrl("http://localhost:8080/searchworkings-news-portlet/spring/org_searchworkings_news_service_spring_NewsService-http");
		factory.setServiceInterface(NewsService.class);

		factory.setHttpInvokerRequestExecutor(new SimpleHttpInvokerRequestExecutor() {
			@Override
			protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException {
				super.prepareConnection(con, contentLength);
				con.setRequestProperty("Authorization", "Basic " + new String(Base64.encodeBase64("username:password".getBytes())));
			}
		});
		factory.afterPropertiesSet();

		NewsService newsService = (NewsService) factory.getObject();

		System.out.println(newsService.getNews(32830L));
	}
}



The ConfigurationFactoryUtil.setConfigurationFactory crap unfortunately is needed because Liferay foolishly loads properties when a service builder entity is constructed
thumbnail
Rishi Dev Gupta, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Expert Beiträge: 255 Beitrittsdatum: 23.11.08 Neueste Beiträge
Thanks Jelmer...
the example code above is working...
Only thing i was trying earlier is that i was trying to access these services through tunnel-web which was wrong. As plugins ext and liferay root having being loaded in the same context can access services interchangibly but not that of plugins portlet which does not have same class loaders.

Rishi
thumbnail
jelmer kuperus, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Liferay Legend Beiträge: 1191 Beitrittsdatum: 10.03.10 Neueste Beiträge
Well i guess you could do that too. But you would have to place your service jar in tomcats global classpath and change the application context defined in tunnel-web so deployment will be a bit more involved. On the upside i think in that case the service might serialize the clp models that might not exhibit the problem of trying to load a property file during construction
thumbnail
Rishi Dev Gupta, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Expert Beiträge: 255 Beitrittsdatum: 23.11.08 Neueste Beiträge
Right...
the approach you have given seems to pretty stable one... thus i am going with it...
thumbnail
Rishi Dev Gupta, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Expert Beiträge: 255 Beitrittsdatum: 23.11.08 Neueste Beiträge
hi

this approach works fine when i am accessing default liberay model objects over the wire like user etc. but i have created a new service model for my custom table and if i return that object from spring http invoker service in plugin portlet it gives the following error ...



org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [http://lo
calhost:8080/core-portlet/spring/com_plat_v2_portlet_service_spring_RegClientAppService-http]; n
ested exception is java.lang.ExceptionInInitializerError
        at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.convertHttpInvokerAccessExcep
tion(HttpInvokerClientInterceptor.java:212)
        at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInter
ceptor.java:145)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.jav
a:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy317.addRegClientApp(Unknown Source)
        at org.apache.jsp.jsp.hello_jsp._jspService(hello_jsp.java:133)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)


jelmer i am struck here, if you have any idea kindly share. how to get my custom model working.

Rishi
thumbnail
Rishi Dev Gupta, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Expert Beiträge: 255 Beitrittsdatum: 23.11.08 Neueste Beiträge
Hi Masroor

Have you got this thing working... if yes kindly share
thumbnail
Rishi Dev Gupta, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Expert Beiträge: 255 Beitrittsdatum: 23.11.08 Neueste Beiträge
Its kind of urgent... if anybody please revert back
thumbnail
jelmer kuperus, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Liferay Legend Beiträge: 1191 Beitrittsdatum: 10.03.10 Neueste Beiträge
I can't tell from the stacktrace. You'll need to figure out why the ExceptionInInitializerError exception is raised. Possibly you'll find more information in the log. Otherwise attach a debugger and set a breakpoint on that exception
thumbnail
Rishi Dev Gupta, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Expert Beiträge: 255 Beitrittsdatum: 23.11.08 Neueste Beiträge
Thanks for prompt reply... as per your earlier comments

The ConfigurationFactoryUtil.setConfigurationFactory crap unfortunately is needed because Liferay foolishly loads properties when a service builder entity is constructed


got it working.... ITs the same issue that while constructing any service builder entity it tries to load the properties file i.e service.properties.
The same things works for UserModel but not for the custom model entity created in plugins environment.

I gave a default value where configurations were accessed and it worked

Rishi
thumbnail
Masroor Khan, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Regular Member Beiträge: 124 Beitrittsdatum: 09.09.08 Neueste Beiträge
Hi Jelmer Kuperus,

Thank you very much for your reply.

It is looking like useful. I am going through steps. And will let you know.


Regards,

Masroor Khan
thumbnail
Masroor Khan, geändert vor 12 Jahren.

RE: how to integrate Spring's HTTP invoker Liferay6.0.5

Regular Member Beiträge: 124 Beitrittsdatum: 09.09.08 Neueste Beiträge
Thanks Jelmer,

This is working fine.


Regards,

Masroor Khan