|
|
|
|
|
|
|
|
|
|
|
Re: Calling Scout from Mobile Device [message #1441882 is a reply to message #1441780] |
Fri, 10 October 2014 10:05 |
Dennis Geesen Messages: 46 Registered: June 2014 |
Member |
|
|
I've got it. To roughly sketch the solution for integrating Jersey into Scout:
First, download the Jersey ( I used 2.13) libraries and add the bunch of jars them to the build path. To avoid any side-effects due to potential OSGi-classloading issues, I currently have all jersey jars in a lib folder of the scout server-plugin.
First we have a resource, I call it Hello
package de.scout.test.rest.server;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.eclipse.scout.commons.exception.ProcessingException;
import org.eclipse.scout.service.SERVICES;
@Path("/hello")
public class Hello {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
try {
String result = SERVICES.getService(IHelloService.class).getGreetings();
return "{" + "SAY: " + result + "}";
}
catch (ProcessingException e) {
e.printStackTrace();
}
return "";
}
Create a JerseyApplication to define the resources that should be provided by Jersey. Although Jersey normally has a package lookup mechanism, this doesn't work for me. Maybe I will check this in the future.
package de.scout.test.rest.server;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class JerseyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> result = new HashSet<Class<?>>();
result.add(Hello.class);
return result;
}
}
Since the rest request is called in another thread than the normal server session is running, we use an own servletcontainer to wrap the request. For this, I created a ProxyServletContainer. Each request is passed by the service method and is delegated to the "normal" jersey ServletContainer, but uses the scout ServerSession (Thread) for this. This "custom servlet" is also discussed here: https://www.eclipse.org/forums/index.php/t/827899/ and I only show the interesting parts:
package de.scout.test.rest.server;
//...
import org.glassfish.jersey.servlet.ServletContainer;
//...
public class ProxyServletContainer extends ServletContainer {
//....
@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
try {
lazyInit(request, response);
Subject subject = new Subject();
subject.getPrincipals().add(new SimplePrincipal("server"));
UserAgent agent = UserAgent.createDefault();
if (subject != null && agent != null) {
IServerSession session = lookupScoutServerSessionOnHttpSession(request, response, subject, agent);
ServerJob serverJob = new ServerJob("Transactional handler", session, subject) {
@Override
protected IStatus runTransaction(IProgressMonitor monitor) throws Exception {
ServletContainer sc = new ServletContainer();
sc.init(getServletConfig());
sc.service(request, response);
return Status.OK_STATUS;
}
};
serverJob.setSystem(true);
serverJob.runNow(new NullProgressMonitor());
}
else {
throw new ServletException("could not create subject or agent!");
}
}
catch (ProcessingException ex) {
throw new ServletException(ex);
}
}
//....
}
Finally you have to register the ProxyServletContainer to the erquinox http service by adding an entry to the extension point. Add the following to the plugin.xml of the server plugin:
<servlet
alias="/rest"
class="package de.scout.test.rest.server.ProxyServletContainer">
<init-param
name="javax.ws.rs.Application"
value="package de.scout.test.rest.server.JerseyApplication">
</init-param>
</servlet>
All Jersey resources are now published to /rest/*, so the Hello.class is publishd to http://localhost:8080/rest/hello (if your scour server is running on 8080).
And it is possible to directly use the SERVICES class to call any service.
Next thing should be a security filter that filters all request on /rest/*...
|
|
|
Powered by
FUDForum. Page generated in 0.04649 seconds