How to use Unicode (UTF-8) with Tomcat, Java, PostgreSQL and JDBC?

I will show you on a real example where we will create a simple page with form to enter Unicode strings and display them. The strings will be saved to PostgreSQL database. Note that in our previous article we showed how it all works with MySQL. We will create UTF-8 database and use JDBC to connect to it from our JSP code. Let’s go!

Create a Unicode database and a database user using cPanel or command line (if you have superuser access). JVM Host provides cPanel to our clients.

postgres=# CREATE USER unicodeuser WITH PASSWORD 'mypass123';
postgres=# CREATE DATABASE unicode WITH ENCODING 'UTF8' OWNER unicodeuser;
postgres=# GRANT ALL ON DATABASE unicode TO unicodeuser;
postgres=# \c unicode
unicode=# CREATE TABLE person (name text);
unicode=# ALTER TABLE person OWNER TO unicodeuser;
unicode=# \q

PostgreSQL driver connection string looks like “jdbc:postgresql://[hostname]:[port]/[db_name]”. You can find the driver on PostgreSQL website at http://jdbc.postgresql.org/. Put the driver jar into your Tomcat lib directory e.g. ~/apache-tomcat-7.0.5/lib/postgresql-9.0-801.jdbc4.jar so that we can use JDBC classes for connecting to PostgreSQL. You may want to restart Tomcat for the classes to be visible server wide. JVM Host clients can use JVMCP control panel for restarting their application server.

Now put the following index.jsp to one of your Tomcat webapps. In our example we put it into ~/apache-tomcat-7.0.5/webapps/ROOT for easy access at root URL of our testing domain. There are a few places in the code where UTF-8 is referenced.

<%@page pageEncoding="UTF-8" language="java" import="java.sql.*"%>
<%@page contentType="text/html;charset=UTF-8"%>
<html><head><META http-equiv="Content-Type" content="text/html;charset=UTF-8"></head><body>

<%
 try{
    request.setCharacterEncoding("UTF-8");
  } catch(Exception e) {}

  out.println("encoding is "+request.getCharacterEncoding());
  out.println("<br/>testing unicode string is 'Miłością'");
  out.println("<br/>request.getLocale() is "+request.getLocale());
  out.println("<br/>response.getLocale() is "+response.getLocale());

  String name = (String)request.getParameter("name");

  java.sql.Connection conn = null;
  try {
    Class.forName("org.postgresql.Driver").newInstance();
    String jdbc = "jdbc:postgresql://localhost/unicode?user=unicodeuser&password=mypass123";
    conn = DriverManager.getConnection(jdbc);
    String sql = "SELECT name FROM person";
    Statement st = conn.createStatement();

    if(name != null){
// uncomment below line if URIEncoding="UTF-8" is not set in Connector in server/xml
//      name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");
// comment out below line if URIEncoding="UTF-8" is not set in Connector in server/xml
      name = new String(request.getParameter("name"));
      out.println("<br/>parameter sent is "+name); 
      String sqlInsert = "INSERT INTO person VALUES ('"+name+"')";
      out.println("<br/>sqlInsert="+sqlInsert);
      st.execute(sqlInsert);
    }

    ResultSet rs = st.executeQuery(sql);
    out.println("<hr>");
    while(rs.next()) { out.print( rs.getObject(1) + "<br/>"); }

  conn.close();
  } catch( Exception ex ) { ex.printStackTrace( new java.io.PrintWriter(out)); }

  %>

  <hr>    
  <form method="GET" action="index.jsp" accept-charset="UTF-8">
    <input type="text" name="name" size="20"><input type="submit" value="Submit" name="Submit"></p>
  </form>   
  </body>
</html>

You can then access and try the form at your root URL e.g. http://username.jvmhost.net/ or http://username.jvmhost.net:HTTPPORTNUMBER/ if you have an account with JVM Host. By default request parameters and values are ISO-8859-1 encoded so you may need to decode them with

name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");

Alternatively, you can tell Tomcat to to do the encoding/decoding for you using URIEncoding=”UTF-8″. Below this setting is activated for both HTTP and AJP connectors as both are used by default at JVM Host. You can add URIEncoding in server.xml.

<Connector port="10104" protocol="AJP/1.3" redirectPort="10105" URIEncoding="UTF-8" />
<Connector port="10106" protocol="HTTP/1.1" 
    connectionTimeout="20000" redirectPort="10105" URIEncoding="UTF-8" />

With this setting active you can just use

name = new String(request.getParameter("name"));

This way you can have any international characters hardcoded in your pages display correctly. Also international characters sent to database via the form are read back and displayed correctly.

This entry was posted in Databases, Java, Tomcat. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


seven × = fifty six

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>