Implementing WURFL Cloud API in java using playframework

adsbrook
Posts: 3
Joined: Tue Jul 23, 2013 5:31 am

Implementing WURFL Cloud API in java using playframework

Postby adsbrook » Tue Jul 23, 2013 5:42 am

Hi..

I have been trying to implement the WURFL Cloud API in my application using the play framework 1.2.4. Unfortunately, play doesn't have the HttpServletRequest and HttpServletResponse nonetheless has a Request and a Response object that can be cast to HttpServeletRequest and HttpServletResponse but when i tried this, i had a NullPointerException .... can any one please help me address this issue or better still guide me as to the implementation. I also looked at this module (https://github.com/revbingo/play-wurfl) but there is little information as to its implementation..

below is my code snippet

Code: Select all

package controllers;

import play.*;
import play.mvc.*;
import play.mvc.Http.Request;
import play.mvc.Http.Response;
import play.mvc.Http.Header;
import play.server.ServletWrapper;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.scientiamobile.wurflcloud.CloudClientLoader;
import com.scientiamobile.wurflcloud.CloudClientManager;
import com.scientiamobile.wurflcloud.device.AbstractDevice;
import com.sun.xml.internal.ws.client.RequestContext;

import net.sourceforge.wurfl.core.Device;
import net.sourceforge.wurfl.core.WURFLHolder;
import net.sourceforge.wurfl.core.WURFLManager;

import models.*;

public class Application extends Controller {
	private static final String API_KEY = "xxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
	
    public static void index() throws Exception {    	
    	HttpServletRequest request = (HttpServletRequest) Request.current().args.get(ServletWrapper.SERVLET_REQ);    	
    	HttpServletResponse response = (HttpServletResponse) Request.current().args.get(ServletWrapper.SERVLET_RES);
    	   	
    	CloudClientLoader loader = new CloudClientLoader(API_KEY);
    	CloudClientManager manager = (CloudClientManager) loader.getClientManager();
    	
//    	Request request = Request.current();
//    	Response response = Response.current();
    	
    	try{
    		AbstractDevice device = manager.getDeviceFromRequest(request,response);
    		Object deviceCapability = device.getCapabilities();
    		
    		render(request, response, deviceCapability);
    	}catch(NullPointerException ex){
    		render(request, response);
    	}
    }
}
Last edited by adsbrook on Tue Jul 23, 2013 7:02 am, edited 1 time in total.

fulvio.crivellaro
Posts: 38
Joined: Tue Jan 31, 2012 10:27 am

Re: Implementing WURFL Cloud API in java using playframework

Postby fulvio.crivellaro » Tue Jul 23, 2013 6:34 am

Hello.
Can you please send us the stack trace of the exception?
HttpServletRequest is actually an interface, hence we need to understand why Play framework implementation causes this NPE.

Fulvio

adsbrook
Posts: 3
Joined: Tue Jul 23, 2013 5:31 am

Re: Implementing WURFL Cloud API in java using playframework

Postby adsbrook » Tue Jul 23, 2013 8:18 am

Hi Fulvio,

Thanks for the effort so far. Please find below the stacktrace

Code: Select all

13:13:47,871 ERROR ~ 

@6f3ib2in0
Internal Server Error (500) for request GET /

Execution exception (In /app/controllers/Application.java around line 35)
NullPointerException occured : null

play.exceptions.JavaExecutionException
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:231)
	at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException
	at com.scientiamobile.wurflcloud.CloudClient.initialize(CloudClient.java:131)
	at com.scientiamobile.wurflcloud.CloudClient.<init>(CloudClient.java:106)
	at com.scientiamobile.wurflcloud.CloudClientManager.getDeviceFromRequest(CloudClientManager.java:140)
	at com.scientiamobile.wurflcloud.CloudClientManager.getDeviceFromRequest(CloudClientManager.java:129)
	at controllers.Application.index(Application.java:35)
	at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
	at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:478)
	at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
	at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
	... 1 more
I also figured out that this is as a result of fetching the response from the request

Code: Select all

HttpServletResponse response = (HttpServletResponse) Request.current().args.get(ServletWrapper.SERVLET_RES);
since it returns null and can't figure out how to get the HttpServletResponse. Will be glad to hear from you.

fulvio.crivellaro
Posts: 38
Joined: Tue Jan 31, 2012 10:27 am

Re: Implementing WURFL Cloud API in java using playframework

Postby fulvio.crivellaro » Tue Jul 23, 2013 11:28 am

Thanks for the code snippet.
I will investigate the problem and provide you an answer as soon as possible.

Fulvio

adsbrook
Posts: 3
Joined: Tue Jul 23, 2013 5:31 am

Re: Implementing WURFL Cloud API in java using playframework

Postby adsbrook » Wed Jul 24, 2013 6:26 am

Thank you.

fulvio.crivellaro
Posts: 38
Joined: Tue Jan 31, 2012 10:27 am

Re: Implementing WURFL Cloud API in java using playframework

Postby fulvio.crivellaro » Wed Jul 24, 2013 7:45 am

The problem seems to be that the Play Framework is not wrapping the HTTP Request correctly, so it is not a problem of the Cloud API. I suggest that you look into the play framework and interact with the owner of that project to get the features fixed.
Building a self-contained example with complete source code is probably a good idea.

Fulvio

fulvio.crivellaro
Posts: 38
Joined: Tue Jan 31, 2012 10:27 am

Re: Implementing WURFL Cloud API in java using playframework

Postby fulvio.crivellaro » Fri Jul 26, 2013 6:26 am

Taking a look at the github link you posted, the way it gets the request is different: request is actually a protected field in the Controller class you are already extending.
First of all, I would try to use it instead of Request.current(), as it is suggested here: http://stackoverflow.com/a/17006963/2617826

Anyway, there exists another approach, which is valid for using the Cloud client without the HttpServletRequest for any reason.

If you still get a null reference, notice that HttpServletRequest is an interface, hence you could just write a wrapper, from Play Framework play.mvc.Http.Request. WURFL should only use HttpServletRequest.getHeader() and HttpServletRequest.getHeaderNames() methods to perform the matches. You can try to wrap the play.mvc.Http.Request like this:

Code: Select all

import play.mvc.Http.Request;

class HttpServletRequestWrapper implements HttpServletRequest {

    private Http.Request mRequest;

    public HttpServletRequestWrapper(Http.Request request) {
        mRequest = request;
    }

    public String getHeader(String name) {
        Http.Header header = mRequest.headers.get(name);
        if (header != null) {
            return header.value();
        } else {
            return null;
        }
    }

    public Enumeration<String> getHeaderNames() {
        Vector<String> headerNames = new Vector<String>();
        for (String header : mRequest.headers.keySet()) {
            headerNames.add(header);
        }
        return headerNames.elements();
    }
}
and returning null for all others inherited methods.
Of course, this is a specific wrapper PlayFramework>HttpServletRequest, but can be extended for any purpose.


Who is online

Users browsing this forum: No registered users and 6 guests