Sunday, September 18, 2011

Android - Integrate Jetty Server In Your Application

First Add the following 6 JARs in your project
Import the following packages:

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

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;



then Add the following Function:


public static final int SERVERPORT = 1234;



Handler handler = new AbstractHandler()
    {
    //@Override
public void handle(String target, Request request, HttpServletRequest MainRequestObject,
HttpServletResponse response) throws IOException, ServletException
{
try
{
//How to get Query String/
Log.i("Query String", target);

//URI format
//http://127.0.0.1:1234/Function/para1/para2

//Http Request Type: GET/POST/PUT/DELETE
Log.i("HTTP Verb", MainRequestObject.getMethod());

BufferedReader in = new BufferedReader(new InputStreamReader(MainRequestObject.getInputStream()));
String line = null;
                 
StringBuilder PostedData = new StringBuilder();

while ((line = in.readLine()) != null)
{    
Log.i("Received Message Line by Line", line);
PostedData.append(line);
}

//Http Request Data Type
Log.i("Posted Data Type", MainRequestObject.getContentType());

//Http Request Type: GET/POST/PUT/DELETE
Log.i("Posted Data", PostedData.toString());

//How To Send Responce Back
response.setContentType("text/html");
           response.setStatus(HttpServletResponse.SC_OK);
           response.getWriter().println("<h1>Hello</h1>");
           ((Request)MainRequestObject).setHandled(true);
}
        catch (Exception ex)
        {
        Log.i("Error", ex.getMessage());
}
}
    };

In "onCreate" function:

Server server = new Server(SERVERPORT);
server.setHandler(handler);
server.start();


*Now you can handle all the HTTP request from with-in your android app.

25 comments:

  1. i tried your code but eclipse give the following error

    [2012-02-07 00:42:57 - Stream] Error generating final archive: Found duplicate file for APK: about.html
    Origin 1: I:\Documents and Settings\user\Desktop\jar files\jetty-continuation-8.0.1.v20110908.jar
    Origin 2: I:\Documents and Settings\user\Desktop\jar files\jetty-http-8.0.1.v20110908.jar

    ReplyDelete
    Replies
    1. There's a "about.html" in 2-3 jar files just open the jar files in WinRaR or other app and remove it from JAR files then re-build your app, it should work fine then

      Delete
  2. My project is to stream video over http(over vlc) ,can you please tell me how can I use the Jetty server for streaming purpose and if yes then please give me the code or give me some suggestion .

    ReplyDelete
    Replies
    1. Check out the following link: http://developer.android.com/guide/topics/media/mediaplayer.html

      Delete
  3. Hi
    From where can I download the 6 JAR files that you mentioned? Can you please provide me the link?
    Thanks in advance

    ReplyDelete
  4. Thank you Buddy, I managed to download those from http://repo2.maven.org/maven2/org/eclipse/jetty/

    ReplyDelete
  5. Thank you Zeeshan!

    I can extract URI parameters from a HTTP_GET.

    How can I extract parameters from a HTTP-POST? (only String parameters, not files).

    ReplyDelete
    Replies
    1. According to My knowledge you can't just retrieve one value from the posted value array you have to parse the whole value to get what you are looking for..for that you can try this:

      HttpClient httpclient = new DefaultHttpClient();
      HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

      try
      {
      // Add your data
      List nameValuePairs = new ArrayList(2);
      nameValuePairs.add(new BasicNameValuePair("id", "12345"));
      nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

      // Execute HTTP Post Request
      HttpResponse response = httpclient.execute(httppost);
      HttpEntity entity = response.getEntity();
      String ResponseString = entity.toString();

      }
      catch (ClientProtocolException e)
      {
      // TODO Auto-generated catch block
      }
      catch (IOException e) {
      // TODO Auto-generated catch block
      }

      Delete
    2. OK, Zeeshan, but that code is for SENDING an http-post. Not receiving/parsing the http post. ;)

      I haven't found any function which could help me parse http-post. JETTY documentation is not so good. :((

      Thank you.

      Delete
  6. Hmmm... the web server responds too late many times (10-15secs). And other times responds quickly.

    Is Jetty managing correctly the 3G/Wifi connection (with WakeLocks to keep the interface ON, for example) ?? Or what else could be the reason?

    Thanks.

    ReplyDelete
    Replies
    1. Ok. Problem solved. If I set up my Android device as HotSpot I don't have any delays when trying to connect. :)

      PS: Previously, I was connecting my Android device to a Wifi network, and one client sending http's to my Android device. Maybe Android was switching off the Wifi interface to save battery and that's why it took too long to connect many times. :)

      Delete

    2. Must forward port address as

      adb -e forward tcp:1234 tcp:1234


      MainRequestObject.getContentType() is null and causes a null pointer exception

      Delete
  7. Hi,

    I am new to android,
    I am developing some basic web application on android.
    I have Linux pc with ubuntu 10.4 with android installed,
    I want to know if i want to put jetty for android in application layer,what changes or steps required to do so

    ReplyDelete
    Replies
    1. I don't think you need to do anything differently, just follow the steps as shown, it should work properly for you too as jetty integration is not using anything related to the OS.

      Delete
  8. Hi,

    Thanks for sharing this with us.

    I am getting this error:


    12-02 09:49:48.424: E/AndroidRuntime(4383): java.lang.NoClassDefFoundError: com.hobbyistsoftware.android.vlcrstreamer_free.streaming_screen_videoview$1
    12-02 09:49:48.424: E/AndroidRuntime(4383): at com.hobbyistsoftware.android.vlcrstreamer_free.streaming_screen_videoview.(streaming_screen_videoview.java:48)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at java.lang.Class.newInstanceImpl(Native Method)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at java.lang.Class.newInstance(Class.java:1319)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.app.ActivityThread.access$600(ActivityThread.java:141)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.os.Handler.dispatchMessage(Handler.java:99)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.os.Looper.loop(Looper.java:137)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at android.app.ActivityThread.main(ActivityThread.java:5039)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at java.lang.reflect.Method.invokeNative(Native Method)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at java.lang.reflect.Method.invoke(Method.java:511)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    12-02 09:49:48.424: E/AndroidRuntime(4383): at dalvik.system.NativeStart.main(Native Method)

    Any help will be appreciated !

    ReplyDelete
  9. Thanks for sharing this with us. I am starting with programming for android. I have question: I have following errrors. Does somebody can help me ?
    Thank you

    FATAL EXCEPTION: main
    ava.lang.NoClassDefFoundError: com.example.serwernowznowz.MainActivity$1
    at com.example.serwernowznowz.MainActivity.(MainActivity.java:39)
    at java.lang.Class.newInstanceImpl(Native Method)
    at java.lang.Class.newInstance(Class.java:1319)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1974)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    at android.app.ActivityThread.access$600(ActivityThread.java:130)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)

    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)

    ReplyDelete
    Replies
    1. The error is saying it can't find the class you are accessing...did you add the activity class in AndroidManifest.xml?

      Delete
    2. I have added Internet permission and there is also





      Delete
    3. I'm not talking about adding Internet Permission, I'm talking about adding activity. Check this link.

      http://www.itcsolutions.eu/2011/08/31/android-tutorial-how-to-create-a-new-activity-class-with-manifest-editor/

      Delete
    4. Thank you. I have created new project, checked manifest and activity starts. But now I have following errors:
      2013-01-25 19:27:22.364:INFO:oejs.Server:jetty-8.0.y.z-SNAPSHOT
      2013-01-25 19:27:22.400:WARN:oejuc.AbstractLifeCycle:FAILED SelectChannelConnector@0.0.0.0:1234 FAILED: java.net.SocketException: socket failed: EACCES (Permission denied)
      java.net.SocketException: socket failed: EACCES (Permission denied)
      at libcore.io.IoBridge.socket(IoBridge.java:583)
      at java.net.PlainSocketImpl.create(PlainSocketImpl.java:201)
      at java.net.PlainServerSocketImpl.create(PlainServerSocketImpl.java:38)
      at java.net.ServerSocket.(ServerSocket.java:59)
      at java.nio.ServerSocketChannelImpl$ServerSocketAdapter.(ServerSocketChannelImpl.java:110)
      at java.nio.ServerSocketChannelImpl.(ServerSocketChannelImpl.java:50)
      at java.nio.SelectorProviderImpl.openServerSocketChannel(SelectorProviderImpl.java:45)
      at java.nio.channels.ServerSocketChannel.open(ServerSocketChannel.java:60)
      at org.eclipse.jetty.server.nio.SelectChannelConnector.open(SelectChannelConnector.java:159)
      at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:300)
      at org.eclipse.jetty.server.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:244)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
      at org.eclipse.jetty.server.Server.doStart(Server.java:273)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
      at com.example.najnowszy.MainActivity.onCreate(MainActivity.java:76)
      at android.app.Activity.performCreate(Activity.java:5008)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
      at android.app.ActivityThread.access$600(ActivityThread.java:130)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loop(Looper.java:137)
      at android.app.ActivityThread.main(ActivityThread.java:4745)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:511)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
      at dalvik.system.NativeStart.main(Native Method)
      Caused by:
      libcore.io.ErrnoException: socket failed: EACCES (Permission denied)
      at libcore.io.Posix.socket(Native Method)
      at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:181)
      at libcore.io.IoBridge.socket(IoBridge.java:568)
      at java.net.PlainSocketImpl.create(PlainSocketImpl.java:201)
      at java.net.PlainServerSocketImpl.create(PlainServerSocketImpl.java:38)

      Delete
    5. Now its a permission issue. You need to give appropriate permissions.

      Delete
  10. Hello, your work is very impressive to me. And I am working on a small toy project like a remote camera. I would like to use one phone as a cam, it send preview image frames (prob. 600x480) at 10-15f/s (WIFI), and I want to check the frame seq. in another phone or PC and can push 'button' to send back to the cam phone to take pictures. Could you give me some hint by using the Jetty? I think jetty is good enough working as server, but how to set up the HTTP connection?
    Best,

    ReplyDelete
    Replies
    1. Can you clarify what you want to do, I mean do you want to do a HTTP request or do you want to access emulator through PC or other mobile evice?

      Delete
    2. Thank you very much for your reply. I want to use one phone as a camera and it can generate preview frames around 10-15 fps, and it works as a server, so that I can see the image frames in another phone, most likely in a browser to check the images, and if see a good one, I can push botton and the cam phone takes picture. I would like to test this framework in a WIFI environment.

      Delete