Connecting Android with external server (Java Servlet + XML)

Combining mobile application with an external server is often important part for many services, so in this tutorial will be presented how such connection can be created using the basic functions of an android, Java servlets, and XML.

 

Here we will creat software which allows to send object ‘book’ over the internet and received back its modified version. Let’s start with the server part. We create a simple class that represents book:
 

public class Book {

	private String title;
	private String author;
	private int pages;
	private String ISBN;
	private int rating;
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public int getPages() {
		return pages;
	}
	public void setPages(int pages) {
		this.pages = pages;
	}
	public String getISBN() {
		return ISBN;
	}
	public void setISBN(String ISBN) {
		this.ISBN = ISBN;
	}
	public int getRating() {
		return rating;
	}
	public void setRating(int rating) {
		this.rating = rating;
	}
}

And servlet which will handle the requests coming from the android:
 


@WebServlet(name = "androidServlet", urlPatterns = { "/index", "", "/androidServlet" })
public class androidServlet extends HttpServlet{
	
	public androidServlet() {
		super();
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		getDataFromAndroid(request,response);

	}
	
	
	public synchronized void getDataFromAndroid(HttpServletRequest request, HttpServletResponse response) {
		try {
	
			byte[] input = getInputData(request);
			String recievedString = new String(input);

			Book book = deserializeData(recievedString, Book.class);
			
			Random rand = new Random();
			book.setRating(rand.nextInt(10));
			StringWriter bookWithRating = serializeData(book);
			
			response.setStatus(HttpServletResponse.SC_OK);
			OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
			writer.write(bookWithRating.toString());
			writer.flush();
			writer.close();

		} catch (IOException e) {
			try {
				response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
				response.getWriter().print(e.getMessage());
				response.getWriter().close();
			} catch (IOException ioe) {
			}
		}

	}
	
	public synchronized byte[] getInputData(HttpServletRequest request) throws IOException {

		int length = request.getContentLength();
		byte[] input = new byte[length];
		ServletInputStream sin = request.getInputStream();
		int c, count = 0;
		while ((c = sin.read(input, count, input.length - count)) != -1) {
			count += c;
		}
		sin.close();

		return input;

	}
	
	public synchronized <T> T deserializeData(String recievedString, Class<T> myclass) {
		Serializer serializer = new Persister();
		T readObjects = null;
		try {
			readObjects = serializer.read(myclass, recievedString);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return readObjects;
	}
	
	public synchronized <T> StringWriter serializeData(T writeObjects){
		Serializer serializer = new Persister();
		StringWriter send = new StringWriter();
		try {
			serializer.write(writeObjects, send);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return send;
	}
}

At the beginning method getInputData(request) gets all input data sent by the android in the form of bytes. Then we create a String from byte array. The android program is created so that we send only xml representng book object which can be immediately deserialized. Serialization and deserialization methods are generic and can be used on for other classes not only Book. Next we randomly select a number in the range of 0-10 and assign it to just received book. At the end of the re-serializes object and send it back to android.
& Nbsp;
To serialize and deserialize objects to XML I use library ‘simple’. If you want to get the same effect, do not forget to add it to Maven

<dependency>
	<groupId>org.simpleframework</groupId>
	<artifactId>simple-xml</artifactId>
	<version>2.7.1</version>
</dependency>

and gradle

compile 'org.simpleframework:2.7.1'

But if you want you can use JSON or other data format.
 
Let’s get to the part related to android. Here we also create the same class Book:
 

public class Book {

	private String title;
	private String author;
	private int pages;
	private String ISBN;
	private int rating;
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public int getPages() {
		return pages;
	}
	public void setPages(int pages) {
		this.pages = pages;
	}
	public String getISBN() {
		return ISBN;
	}
	public void setISBN(String ISBN) {
		this.ISBN = ISBN;
	}
	public int getRating() {
		return rating;
	}
	public void setRating(int rating) {
		this.rating = rating;
	}
	
}

MainActivity where we give information about book and recive feedback:
 


public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		final EditText title = (EditText) findViewById(R.id.Title);
		final EditText author = (EditText) findViewById(R.id.Author);
		final EditText pages = (EditText) findViewById(R.id.Pages);
		final EditText ISBN = (EditText) findViewById(R.id.ISBN);
		final TextView rating = (TextView) findViewById(R.id.Rating);

		Button send = (Button) findViewById(R.id.Send);
		send.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				Book someBook = new Book();
				someBook.setAuthor(author.getText().toString());
				someBook.setTitle(title.getText().toString());
				someBook.setPages(Integer.valueOf(pages.getText().toString()));
				someBook.setAuthor(ISBN.getText().toString());

				new sendUrlToServlet(MainActivity.this, someBook, rating).execute();
			}
		});
	}
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.android_connector.MainActivity" >

    <EditText
        android:id="@+id/Title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Title" />

    <EditText
        android:id="@+id/Author"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Author" />

    <EditText
        android:id="@+id/Pages"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Pages" />

    <EditText
        android:id="@+id/ISBN"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="ISBN" />

    <Button
        android:id="@+id/Send"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send" />

    <TextView
        android:id="@+id/Rating"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp" />

</LinearLayout>

And AsyncTask which makes most of the work:
 

class sendUrlToServlet extends AsyncTask<Integer, Void, Integer> {

	private Context con;
	private Book book;
	private Book newBook;
	private TextView resultTextView;


	sendUrlToServlet(Context con,Book book, TextView resultTextView) {
		this.con = con;
		this.book = book;
		this.resultTextView = resultTextView;
	}

	protected void onPreExecute() {

        super.onPreExecute();

	}

	protected void onPostExecute(Integer result) {
		resultTextView.setText("Book " + newBook.getTitle() + " acquired Rating of " + newBook.getRating());
	}

	@Override
	protected Integer doInBackground(Integer... params) {
		HttpURLConnection connection = null;
		try {
				URL url = new URL("http://android-baseconnection.rhcloud.com");
				connection = (HttpURLConnection) url.openConnection();

				connection.setRequestMethod("POST");
				connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
				
				sendData(connection);
				reciveData(connection);
			
				} catch (Exception e) {

				} finally {
					try {
						System.out.println(connection.getResponseCode());
					} catch (IOException e) {
						e.printStackTrace();
					}
					connection.disconnect();
				}
		return null;
			}

	void sendData(HttpURLConnection connection) throws Exception{
		
		Serializer serializer = new Persister();
		StringWriter send = new StringWriter();
		serializer.write(book, send);
		
		BufferedOutputStream out = new BufferedOutputStream(connection.getOutputStream());
		out.write(send.toString().getBytes());
		out.flush();
		out.close();
	}
	
	void reciveData(HttpURLConnection connection) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

		String returnString = "";
		StringBuilder allData = new StringBuilder("");

		while ((returnString = in.readLine()) != null) {
			allData.append(returnString);
		}
		in.close();

		System.out.println(allData.toString());
		
		Serializer serializer = new Persister();
		newBook = serializer.read(Book.class,allData.toString());
	}
			

}

 
In MainActivity there are not many unusual features. We give there basic information about the book and by clicking on the button we start asynchronous task responsible for communication with the servlet. In asynchronic task we create a URL object that specifies the address at which servlet is listening, and the connection parameters. When we send data book object is serilized and send as a byte stream in output. Similarly when receiving data from the server.
 
Example output of the software can be viewed below. Details about the book were sent to the server and there, using a random number, book rating have been evaluated and book object have been sent back to our application:
 
android communication

Leave a Comment

WordPress Video Lightbox Plugin