Archive for the ‘Web’ Category

Google App Engine and sending Emails

Thursday, February 3rd, 2011

One of the nice things in the Google App Engine is that is it very easy to work with emails. You can send out and receive emails in your servlets.

Lets demonstrate this by defining an application which allows the user to give some feedback. The backend servlet should receive this input and send out an email to the admin of the application.

For this we create a new App Engine project “de.vogella.gae.feedback” and create a simple form.

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>A form</title>
 </head>
 <body>
 <form action="feedback" method="post">

  <!-- Simple text field -->
 <label for="name">Name </label>
 <input type="text" name="name"/>
 <br/>

  <!-- Email -->
 <label for="email">Email </label>
 <input type="email" name="email"/>
 <br/>

  <!-- Textarea -->
 <label for="description">Description </label>
 <textarea  name="description" cols="50" rows="5">Type your comment here</textarea>
 <br/>

 <input type="submit" name="submit" value="Send Request"/>
 </form>
 </body>
</html>

Then we define a Servlet under the URL /feedback which will receive the input from the form and send out an email.

 package de.vogella.gae.feedback;

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

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class FeedbackServlet extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String name = req.getParameter("name");
		String description = req.getParameter("description");
		String email = req.getParameter("email");
		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		String msgBody = name + "\n" + description + "\n" + email;

		try {
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress("your_admin@googlemail.com",
					"Your admin"));
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(
					"your_email@example.com", "Your name
			msg.setSubject("Feedback");
			msg.setText(msgBody);
			Transport.send(msg);

		} catch (Exception e) {
			resp.setContentType("text/plain");
			resp.getWriter().println("Something went wrong. Please try again.");
			throw new RuntimeException(e);
		}

		resp.setContentType("text/plain");
		resp.getWriter().println(
				"Thank you for your feedback. An Email has been send out.");
	}
}

You have to make sure that the from email is the admin of the application otherwise you will receive an “Unauthorized Sender” Exception. If you deploy your application, access index.html, enter some data and press submit the person maintained in your recipient should receive an email with the feedback.

You find an example how to receive email in my Google App Engine Tutorial. You should also follow me on Twitter.

Google App Engine and JPA

Monday, January 10th, 2011

Using JPA on the Google AppEngine is straight forward. For some reason the documentation on the official Google App Engine side is not very easy to read therefore a little example here.

Create a new web project “de.vogella.gae.persistence.jpa”. Change the generated Servlet to “PersistsServlet” and adjust the “web.xml”. Create the following two classes. The first will be your tiny data model and the other will buffer the creation of the EntityManagerFactory which can be time consuming.

package de.vogella.gae.persistence.jpa.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Todo {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long todoId;
	private String summary;

	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}
}
package de.vogella.gae.persistence.jpa.model;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EMFService {
	private static final EntityManagerFactory emfInstance = Persistence
			.createEntityManagerFactory("transactions-optional");

	private EMFService() {
	}

	public static EntityManagerFactory get() {
		return emfInstance;
	}
}

Below “src/META-INF” create the following file which will configure JPA for the Google App Engine.

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

    <persistence-unit name="transactions-optional">
        <provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
        <properties>
            <property name="datanucleus.NontransactionalRead" value="true"/>
            <property name="datanucleus.NontransactionalWrite" value="true"/>
            <property name="datanucleus.ConnectionURL" value="appengine"/>
        </properties>
    </persistence-unit>

</persistence>

Now change the code of your servlet to the following. This servlet will create a new Todo every time it is called and displays the today number of Todos to the user.

package de.vogella.gae.persistence.jpa;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import de.vogella.gae.persistence.jpa.model.EMFService;
import de.vogella.gae.persistence.jpa.model.Todo;

@SuppressWarnings("serial")
public class PersistsServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		Todo todo = new Todo();

		todo.setSummary("This is my todo");

		EntityManager em = EMFService.get().createEntityManager();
		List<Todo> todos = null;
		try {
			em.persist(todo);
			Query q = em.createQuery("select t from Todo t");
			todos = new ArrayList(q.getResultList());
		} finally {
			em.close();
		}

		resp.setContentType("text/plain");
		if (todos != null) {
			resp.getWriter().println(
					"Hello, JPA. We have " + todos.size()
							+ " number of entries.");
		} else {
			resp.getWriter().println("Should not happen");
		}
	}
}

Thats it. Run your example and access your servlet. See that the number of entries is increasing every time you hit the servlet.

That’s it! Deploy the application to the Google App Engine to be able to chat with it. Of course where is more to JPA and Google AppEngine but you can use my tutorials to learn more about them.

JPA Tutorial
Google App Engine Tutorial

You can also follow me on Twitter.

Build a “Management” Chat Bot in 5 steps with Google AppEngine

Thursday, December 16th, 2010

Google AppEngine provides very cool features. One of these features is the XMPP API, that allows you to write apps that can interact with users through XMPP clients, e.g. Jabber or GTalk.

Here’s a quick description how to create a chat bot which will help you to work for efficient. I think it has the potential to replace at least some managers. ;-)

1. Create a new web application project “de.vogella.gae.java.chatbot”. Rename the generated servlet “ChatbotServlet” and adjust web.xml
2. Open the servlet class and add a new attribute that provides access to the XMPP service

      private static final XMPPService xmppService =
           XMPPServiceFactory.getXMPPService();

3. Add a doPost method which will be called when a new message is received. In this method I will parse the incoming message and generate a reply, in our case a simple echo.

      public void doPost(HttpServletRequest request, HttpServletResponse response)
          throws IOException {
      Message message = xmppService.parseMessage(request);
      Message reply = new MessageBuilder()
              .withRecipientJids(message.getFromJid())
              .withMessageType(MessageType.NORMAL)
              .withBody(message.getBody())
              .build();
      xmppService.sendMessage(reply);
      }

4. Now we need to enable the XMPP service for our app. Open the appengine-web.xml file in the war/WEB-INF folder and add the following tag:

<inbound-services>
      <service>xmpp_message</service>
</inbound-services>

5. As the final step we need to hook our servlet to a standard URL pattern that is used for the XMPP service. Open the web.xml file in the WEB-INF folder and change the existing servlet mapping:

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
	<servlet>
		<servlet-name>chatbot</servlet-name>
		<servlet-class>de.vogella.gae.java.chatbot.ChatbotServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>chatbot</servlet-name>
    <url-pattern>/_ah/xmpp/message/chat/</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>

That’s it! Deploy the application to the Google App Engine to be able to chat with it.

Every application has it’s own Jabber/GTalk ID: appid@appspot.com or anything@appid.appspot.com. Add that ID to your GTalk list and you will be able to interact with the application.

References: http://code.google.com/appengine/docs/java/xmpp and http://blog.appenginefan.com/2009/09/my-first-attempt-at-xmpp-in-java-app.html.

I would like to thank Ralf Güldemeister for providing most of the content of this blog entry.

To learn more about the Google App Engine please have a look at my Google App Engine Java Tutorial. You can also follow me on Twitter.

Integration of SAP with the Google App Engine

Monday, November 22nd, 2010

Recently I though how I could integrate an SAP System which tends to be in a closed firewall where no access it granded from the outsite. The solution is actually quite easy. You can easily send our HTTP requests from SAP. So you could send out some data from SAP and / or request a status via HTTP from the outsite system.

This blog entry demonstrates how to send out emails from the Google App Engine via a ABAP report. Here is the ABAP report. Your have to replace the “your-appid” with your application id on the Google App Engine.

*&---------------------------------------------------------------------*
*& Report  Z_CALL_GOOGLEAPPENGINE
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  Z_CALL_GOOGLEAPPENGINE.

DATA: client        TYPE REF TO if_http_client,
      host          TYPE string VALUE 'your-appid.appspot.com',
      proxy_host    TYPE string VALUE 'proxy',
      service       TYPE string VALUE '80',
      proxy_service TYPE string VALUE '8080',
      path          TYPE string,
      errortext     TYPE string,
      subrc         TYPE sysubrc,
      response_data TYPE xstring,
      request_data  TYPE xstring,
      txt           TYPE string,
      code          TYPE i,
      reason        TYPE string.

PARAMETERS: s_name(12) TYPE c.
PARAMETERS: s_email(20) TYPE c.
PARAMETERS: s_desc(30) TYPE c.

CONCATENATE '/feedback?name=' s_name '&description='  s_desc  '&email='  s_email into path.

cl_http_client=>create(
  EXPORTING
    host               = host    " Logical destination (specified in function call)
    service            = service    " Port Number
    proxy_host         = proxy_host    " Logical destination (specified in function call)
    proxy_service      = proxy_service    " Port Number
    scheme             = cl_http_client=>schemetype_http    " HTTP/HTTPS
  IMPORTING
    client             = client    " HTTP Client Abstraction
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4
        ).
IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

* Set HTTP method GET (optional, also used when the request contains no body)
*client->request->set_method( if_http_request=>co_request_method_get ).

*client->request->set_version( if_http_request=>co_protocol_version_1_1 ).

* Set request URI (/<path>[?<querystring>])
cl_http_utility=>set_request_uri(
  request = client->request
  uri     = path ).

*client->request->get_raw_message(
*  RECEIVING
*    data = request_data    " HTTP message
*  EXCEPTIONS
*    OTHERS = 1
*).
*IF sy-subrc <> 0.
*  WRITE: / 'Error printing the request'.
*ELSE.
*  MOVE request_data TO txt.
*  WRITE: / 'Request: ', request_data.
*  WRITE: / txt.
*ENDIF.

* Send the request
client->send(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3
    http_invalid_timeout       = 4
    OTHERS                     = 5
).

IF sy-subrc <> 0.
  client->get_last_error(
    IMPORTING
      code    = subrc    " Return Value, Return Value After ABAP Statements
      message = errortext    " Error Message
    EXCEPTIONS
      OTHERS  = 1
  ).
  IF sy-subrc <> 0.
    WRITE: / 'Communication error. Cannot get last error'.
  ELSE.
    WRITE: / 'Communication error( send ), Code: ', subrc, ' Message: ', errortext.
  ENDIF.
  EXIT.
ENDIF.

* Receive the response
client->receive(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3
    OTHERS                     = 4
).
IF sy-subrc <> 0.
  client->get_last_error(
    IMPORTING
      code    = subrc    " Return Value, Return Value After ABAP Statements
      message = errortext    " Error Message
    EXCEPTIONS
      OTHERS  = 1
  ).
  IF sy-subrc <> 0.
    WRITE: / 'Communication error (receive). Cannot get last error'.
  ELSE.
    WRITE: / 'Communication error(send), Code: ', subrc, ' Message: ', errortext.
  ENDIF.
  EXIT.
ENDIF.

client->response->get_status(
  IMPORTING
    code   = code    " HTTP status code
    reason = reason    " HTTP status description
  EXCEPTIONS
    OTHERS = 1
).

WRITE: / 'Response Status Code: ', code, reason.

client->response->get_cdata(
  RECEIVING
    data = txt    " Character data
  EXCEPTIONS
    OTHERS = 1
).

IF sy-subrc <> 0.
  WRITE: / 'Error printing the response'.
ELSE.
*  MOVE request_data TO txt.
*  DATA: conv TYPE REF TO cl_abap_conv_in_ce.
*  conv = cl_abap_conv_in_ce=>create( input = request_data ).
*  conv->read( IMPORTING data = txt ).
*  WRITE: / 'Response: ', response_data.
  WRITE: / txt.
ENDIF.

* Close the connection at the end
client->close(
  EXCEPTIONS
    http_invalid_state = 1
    OTHERS             = 2
).
IF sy-subrc <> 0.
  WRITE: / 'Error on closing the http connection: ', sy-subrc.
ELSE.
  WRITE: / 'Connection closed'.
ENDIF.

The receiving servlet just extract the in the doGet method the information and uses it to send our an email. Here is the servlet code.

package de.vogella.gae.feedback;

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

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class FeedbackServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String name = req.getParameter("name");
		String description = req.getParameter("description");
		String email = req.getParameter("email");
		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		String msgBody = description;
		try {
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress("Your_Admin_Email@googlemail.com",
					"Your Name"));
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(
					email, name));
			msg.setSubject("Feedback");
			msg.setText(msgBody);
			Transport.send(msg);

		} catch (Exception e) {
			resp.setContentType("text/plain");
			resp.getWriter().println("Something went wrong. Please try again.");
			throw new RuntimeException(e);
		}

		resp.setContentType("text/plain");
		resp.getWriter().println(
				"Thank you for your feedback. An Email has been send out.");
	}
}

You find more information about App Engine in my Google App Engine Tutorial. You should also follow me on Twitter.

Making faces – How to display an image for all your blog comments

Wednesday, April 21st, 2010

Have you ever wondered why some people have a friendly face when posting a blog comment while others seems to look quite anonymous? ;-)

Here is one possible solution: Gravatar provides a service which allows you to use a single avatar image across all Gravatar-enabled web sites. Sign up for a free Gravatar account to associate your email address with an avatar image. It definitely seems to be working for WordPress blogs and Ohloh.net.

Even though this entry is not directly Eclipse related I’m putting this blog entry is the Eclipse blog queue in the hope to see more friendly faces in the future.

Integrating Twitter via Java

Thursday, February 11th, 2010

This you want to integrate to Twitter from Java you can use the following library JTwitter.

Try out the twitter integration with the following coding:


package de.vogella.twitter.test;

import java.util.List;

import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.Twitter.User;

public class TwitterTest {
	private static final String user ="your-user";
	private static final String pw ="your-password";

	public static void main(String[] args) {
		// Make a Twitter object
               Twitter twitter = new TwitterFactory().getInstance(user,pw);
		// Print Lars Vogel status
		System.out.println(twitter.getStatus("vogella"));
		// Set my status
		twitter.setStatus("@vogella messing with Twitter in Java");
		List<User> followers = twitter.getFollowers();
		for (User user : followers) {
			System.out.println(user.getName());
		}
	}
}

Another Java Twitter Library is Twitter4J.

How can I use a Java jar file in a Grails application?

Wednesday, February 10th, 2010

After banging my head against the wall in trying to find out how I can use Java class in a Grails application I found out that the solution is embarrassing simple.

Just create a jar file from your Java classes and put the jar file into the folder “jar” of your Grails application.

You also have to add the correct import statement to your Groovy file. E.g. if you want to use class “MyJavaClass” in package “de.vogella.test” you have to add “import de.vogella.test.MyJavaClass” to your Groovy class.

You also need to re-start the grails server.

To learn more about Grails see Grails Tutorial

How to create a transparent background for an image with Gimp

Wednesday, February 10th, 2010

The following will explain how to create an image with a transparent background with the freely available tool Gimp.

GIF and PNG images can have transparent backgrounds. JPEG can not have a transparent background. Lets take the following example picture.

It look good on a white background but not so good on another background.

Start Gimp and open your file via File -> Open and selecting your file.

Select Tools -> Selection Tools -> By Color Select (or another method which is more appropriate to you).

Select in the Layer window Layer -> Transparency -> Add Alpha Channel. Or just use Cntr+X to cut out the selected color.

Save the file in either png or gif format.

Google App Engine – Low level API for storing objects

Monday, January 18th, 2010

Google App Engine for Java permits three ways of storing your data: JDO, JPA and the low-level API. All data is ultimately stored in Bigtable. This blog post will give a little example how you can store data via the low-level API.

The low-level API allows to store entities with their properties directly into the application datastore. Your object which is the database entry will be stored in a row of Bigtable. The fields in your object are represented as properties of the row.

In the low-level API your object is represented by a key, a type (called kind) and a list of key value pairs for the properties. The low-level API allows you use the methods get(), put() and query() on an object called DatastoreService to save and retrieve entities. DatastoreService can be created by the DatastoreServiceFactory.

An entry is identified by its key. To retrieve saved entries you can recreate your key via the method KeyFactory.createKey(kind, value) there kind represent your data type and value the key of this object.

Lets have a look at an example. The following assumes that you have already basic knowledge about web development on the Google App Engine .

Create a new project “de.vogella.gae.java.persistence.lowlevel” and create the following two servlets. The first will create one entry in the datastore the second will retrieve the data.

package de.vogella.gae.java.persistence.lowlevel;

import java.io.IOException;

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

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;

@SuppressWarnings("serial")
public class SaveDataServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		Entity entity = new Entity("Todo", "Todo1");
		// Alternatively use
		// Key todoKey = KeyFactory.createKey("Todo", "Todo1");
		// Entity entity = new Entity(todoKey);
		entity.setProperty("summary", "This is my summary");
		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();
		datastore.put(entity);

		resp.setContentType("text/plain");
		resp.getWriter().println("Saved data");
	}
}
package de.vogella.gae.java.persistence.lowlevel;

import java.io.IOException;

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

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@SuppressWarnings("serial")
public class GetDataServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();
		Key todoKey = KeyFactory.createKey("Todo", "Todo1");
		Entity entity;
		try {
			entity = datastore.get(todoKey);
			String summary = (String) entity.getProperty("summary");

			resp.setContentType("text/plain");
			resp.getWriter()
					.println("Got the todo with the summary " + summary);
		} catch (EntityNotFoundException e) {
			resp.setContentType("text/plain");
			resp.getWriter().println("Entry not found.");
		}

	}
}

If you run this project and hit the URL you mapped the Save servlet to then an entry will get created. If you hit the URL of the get servlet this entries will be read from the datastore.

For another example have a look at my Google App Engine Tutorial. You can also follow me on Twitter here.


Switch to our mobile site