How to use Unicode (UTF-8) with Tomcat, Java, MySQL 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 MySQL database. 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.

mysql> create database unicode character set utf8 COLLATE utf8_bin;
mysql> create user unicode@localhost IDENTIFIED BY 'mypass123';
mysql> grant all on unicode.* to unicode@localhost;
mysql> flush privileges;
mysql> use unicode;
mysql> create table person (name text);
mysql> \q

MySQL Connector/J driver connection string has the form of “jdbc:mysql://[hostname]:[port]/[db_name]“. You can find the driver on MySQL website at http://www.mysql.com/products/connector/j/. Put J/Connector into your Tomcat lib directory e.g. ~/apache-tomcat-7.0.5/lib/mysql-connector-java-5.1.16-bin.jar so that we can use JDBC classes for connecting to MySQL. 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("com.mysql.jdbc.Driver").newInstance();
    String jdbc = "jdbc:mysql://localhost/unicode?user=unicode&password=mypass123";
    String jdbcutf8 = "&useUnicode=true&characterEncoding=UTF-8";
    conn = DriverManager.getConnection(jdbc+jdbcutf8);
    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 SET name='"+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 *

*


four − 2 =

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>