Published on Sep 12 2011 in Databases Java Tomcat

Here goes 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 JCP 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 'Mioci'");
      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.

Getting JSON UTF-8 reply and printing it from JSP

In case you need to query an API endpoint returning UTF-8 encoded JSON from JSP try this code:

URL url = new URL("https://httpbin.org/anything");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Bearer 11111111-2222-3333-4444-555555555555");
connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
connection.setRequestProperty("User-Agent", "curl/7.29.0");
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream (connection.getOutputStream ());
wr.writeBytes ("{\"keye\": \"value\"}");
wr.flush ();
wr.close ();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF8")); // <=== IMPORTANT
String line=reader.readLine();
while(line!=null) { out.println(line);  line = reader.readLine(); }