Java

java programming

Creating a Pretty URL With Struts Framework and URLRewrite

On this tutorial im trying to create a pretty URL using one of java’s most famous framework, Struts Framework. I want to change a usual struts URL from news.do?id=newsID into a pretty URL such as news/newsID/newsTitle. The main benefits are your links get easily indexed by search engines and make them easy-to-read and easy-to-remember.

Im using urlrewrite library for url rewriting. As for this example, im using old version of struts 1.3.8 and iBatis ORM version 2.3.4.

First as always, a simple MySQL table

CREATE TABLE news
    (
        id bigint NOT NULL AUTO_INCREMENT,
        title VARCHAR(100) NOT NULL,
        content text NOT NULL,
        createddate DATETIME NOT NULL,
        PRIMARY KEY (id)
    )
	
insert into news 
        (id, title, content, createddate) 
        values (1, 'A Tale of Two More Earths?', 'Example of Content', '2011-12-26 19:00:00');
insert into news 
        (id, title, content, createddate) 
        values (2, 'India: Boat Capsizes; 11 Missing', 'Example of Content number 2', '2011-12-27 19:00:00');

and a javabean and xml for database mapping. And please be aware, im injecting Slugify class to getUrl method so i could get a clean url property inside this bean.

package com.edw.bean;

import com.edw.util.Slugify;
import java.util.Date;

public class News {

    private Long id;
    private String title;
    private Date createddate;
    private String content;
    
    // added for pretty URL
    private String url;

    // other getter and setter

    // do title formatting for a clean url
    public String getUrl() {
        return Slugify.slugify(getTitle());
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

And this is my xml queries

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="news" >
    
  <resultMap id="newsBean" class="com.edw.bean.News" >    
    <result column="id" property="id" jdbcType="BIGINT" />
    <result column="title" property="title" jdbcType="VARCHAR" />
    <result column="content" property="content" jdbcType="LONGVARCHAR" />
    <result column="createddate" property="createddate" jdbcType="TIMESTAMP" />
  </resultMap>  
  
  <select id="select" resultMap="newsBean" >    
    select id, title, createddate, content
    from news    
  </select> 
  
  <select id="selectWithId" resultMap="newsBean" parameterClass="java.lang.Integer" >    
    select id, title, createddate, content
    from news    
    where id = #id#
  </select> 
  
</sqlMap>

This is my utility java class, its main purpose is to encode and clean news titles so they can fit into URLs.

package com.edw.util;

import java.net.URLEncoder;
import java.text.Normalizer;
import org.apache.log4j.Logger;

public class Slugify {

    private static final Logger logger = Logger.getLogger(Slugify.class);
    
    /**
     * 
     * modified version of Jozef Ševcík's slugify
     * 
     * @link http://maddemcode.com/java/seo-friendly-urls-using-slugify-in-java/
     * @param input
     * @return formatted URL
     */
    public static String slugify(String input) {
        if (input == null || input.length() == 0) {
            return "";
        }
        
        try {
            String toReturn = normalize(input);            
            toReturn = toReturn.replaceAll("[^\\w\\s\\-]", "");
            toReturn = toReturn.replace(" ", "-");
            toReturn = toReturn.toLowerCase();
            toReturn = URLEncoder.encode(toReturn, "UTF-8");
            return toReturn;
        } catch (Exception e) {
            logger.error(e, e);
        }
        return "";

    }

    private static String normalize(String input) {
        if (input == null || input.length() == 0) {
            return "";
        }
        return Normalizer.normalize(input, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
    }
}

And an xml file to load all my xml queries

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <settings
        useStatementNamespaces="true"
        lazyLoadingEnabled="true"
        enhancementEnabled="true"
        maxSessions="20"
        />

    <transactionManager type="JDBC" commitRequired="false">
        <dataSource type="SIMPLE">

            <property name="SetAutoCommitAllowed" value="false"/>
            <property name="DefaultAutoCommit" value="false"/>
            
            <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
            <!-- my database name = pepe -->
            <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/pepe"/>
            <property name="JDBC.Username" value="root"/>
            <property name="JDBC.Password" value="xxx"/>
   
        </dataSource>
    </transactionManager>

    <sqlMap resource="com/edw/sqlmap/news.xml"/>
    
</sqlMapConfig>

A java class to load my xml configuration

package com.edw.sqlmap.config;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.Reader;


public class SqlMapConfig {

    protected static final SqlMapClient sqlMap;

    static {
        try {
            Reader reader = Resources.getResourceAsReader("com/edw/sqlmap/sqlmapconfig.xml");
            sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);       
        } catch (Exception e){
            throw new RuntimeException("Fatal Error.  Cause: " + e, e);
        }
    }

    public static SqlMapClient getSqlMap() {
        return sqlMap;
    }
}

Next is im creating a Struts Action class

package com.edw.action;

import com.edw.bean.News;
import com.edw.sqlmap.config.SqlMapConfig;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public class NewsAction extends org.apache.struts.action.Action {

    private static final String SUCCESS = "success";
    
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        
        List<News> newses = null;
        if(request.getParameter("id") != null)
            newses = SqlMapConfig.getSqlMap().queryForList("news.selectWithId", Integer.parseInt(request.getParameter("id")));       
        else
            newses = SqlMapConfig.getSqlMap().queryForList("news.select");       
        request.setAttribute("newses", newses);
        
        return mapping.findForward(SUCCESS);
    }        
}

dont forget to register NewsAction to strutsconfig.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">

<struts-config>
    <form-beans></form-beans>
    
    <global-exceptions></global-exceptions>

    <global-forwards>
        <forward name="welcome"  path="/Welcome.do"/>
    </global-forwards>

    <action-mappings>
        <action path="/news" type="com.edw.action.NewsAction">
            <forward name="success" path="/WEB-INF/pages/news.jsp" />
        </action>
        <action path="/Welcome" forward="/welcomeStruts.jsp"/>
    </action-mappings>        

    <message-resources parameter="com/edw/res/ApplicationResource"/>    
    
</struts-config>

Next is my presentation layer. Im using a plain JSP and Struts tags, and put my JSP file under WEB-INF folder, so it cant be accessed directly.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>

<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>News Page</title>
    </head>
    <body>
        <h1>News</h1>

        <logic:iterate name="newses" id="news">            
            <bean:write name="news" property="id"/> , 
            <bean:write name="news" property="title"/>, 
            <bean:write name="news" property="createddate"/>, 
            <bean:write name="news" property="content"/>            
            <br />
            <a href="${pageContext.request.contextPath}/news/<bean:write name="news" property="id"/>/<bean:write name="news" property="url"/>">link</a>
            <br />
            <br />
            <br />
            
        </logic:iterate>

    </body>
</html>

Next is where the magic of urlrewrite starts, first i register urlrewrite filter to my web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>   
    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
        
    
    <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>2</param-value>
        </init-param>
        <init-param>
            <param-name>detail</param-name>
            <param-value>2</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
</web-app>

and create a urlrewrite xml under WEB-INF

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
        "http://tuckey.org/res/dtds/urlrewrite3.2.dtd">

<urlrewrite>       
    
    <rule>
        <note>for news with parameters</note>
        <from>^/news/([0-9]+)/(.*)</from>
        <to>/news.do?id=$1</to>
    </rule> 
    
    <rule>
        <note>display all news</note>
        <from>^/news$</from>
        <to>/news.do</to>
    </rule> 

</urlrewrite>

The final result is my url path will be changed from

http://localhost:8084/StrutsPrettyURL/news.do
and
http://localhost:8084/StrutsPrettyURL/news.do?id=1

to

http://localhost:8084/StrutsPrettyURL/news
and
http://localhost:8084/StrutsPrettyURL/news/1/a-tale-of-two-more-earths

This are my netbeans project structure and libraries.

Have Fun (&)

A Simple HTTPS Configuration Example on Apache Tomcat 6

This idea comes suddenly on my head while i was reading a question on Kaskus’ programmer forum about how to setup a https connection on Apache Tomcat, thats why today im trying to write a simple how-to example on creating a simple HTTPS connection using Apache Tomcat 6. Who knows perhaps someone would find it useful.

Let’s start with creating a simple certificate file using keytool.exe

C:\Program Files\Java\jdk1.6.0_19\bin>keytool.exe -genkey -alias tomcat -keyalg RSA -keystore edw.jks

after you insert your keystore password (i entered “secret” as my password) and several simple questions such as “What is your first and last name?”, it would create a file.

What you need to do next is to link your certificate to Tomcat’s server.xml configuration. This is what i add to my server.xml configuration.

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" keystoreFile="D:\edw.jks" 
               keystorePass="secret" />
<!-- keystorePass use the same password -->

And i also add this to my web.xml file, located under my tomcat’s conf folder

	<security-constraint>
		<web-resource-collection>
			<web-resource-name>Automatic SLL Forwarding</web-resource-name>
			<url-pattern>/*</url-pattern>
		</web-resource-collection>
		<user-data-constraint>
			<transport-guarantee>CONFIDENTIAL</transport-guarantee>
		</user-data-constraint>
	</security-constraint>

This is what my page will look like,

Hope it would help others, cheers (B)

How to Create a Simple Servlet to Handle JSon Requests

On this example, im trying to create a simple servlet to handle JSon request. Im using this servlet to handle JSon request from my front end such as web or even desktop application. Thanks to GSon library, it really helped on simplifying javabean convert to json strings and the other way around.

First as usual, a simple java bean to handle request and response format

package com.edw.bean;

public class Student {
 
    private String name;
    private int age;
    private byte gender;

	// other setter and getter
}
package com.edw.bean;

public class Status {
    private boolean success;
    private String description;
	
	// other setter and getter
}

And this is my servlet,

package com.edw.servlet;

import com.edw.bean.Status;
import com.edw.bean.Student;
import com.google.gson.Gson;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JsonParserServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json");        
        Gson gson = new Gson();

        try {
            StringBuilder sb = new StringBuilder();
            String s;
            while ((s = request.getReader().readLine()) != null) {
                sb.append(s);
            }

            Student student = (Student) gson.fromJson(sb.toString(), Student.class);

            Status status = new Status();
            if (student.getName().equalsIgnoreCase("edw")) {
                status.setSuccess(true);
                status.setDescription("success");
            } else {
                status.setSuccess(false);
                status.setDescription("not edw");
            }
            response.getOutputStream().print(gson.toJson(status));
            response.getOutputStream().flush();
        } catch (Exception ex) {
            ex.printStackTrace();
            Status status = new Status();
            status.setSuccess(false);
            status.setDescription(ex.getMessage());
            response.getOutputStream().print(gson.toJson(status));
            response.getOutputStream().flush();
        } 
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

This is a screenshot on how my message actually look like

Have Fun (H)

Creating a Simple Yahoo Messenger Auto Response with Java and OpenYMSG Library

Hi, several days ago someone asked me to help him on his assignment related to Yahoo Messenger Application with Java. That’s why today im trying to help him by creating a simple example on auto response and message sending using one of the best open source Yahoo Messenger API implementation, OpenYMSG.

It’s actually quite easy, only several lines of codes. This is how i do it

package com.edw.yahoo;

import java.util.Scanner;
import org.apache.log4j.Logger;
import org.openymsg.network.FireEvent;
import org.openymsg.network.ServiceType;
import org.openymsg.network.Session;
import org.openymsg.network.event.SessionEvent;
import org.openymsg.network.event.SessionListener;

/**
 *  com.edw.yahoo.YahooLogin
 *
 *  @author edw
 */
public class YahooLogin implements SessionListener {

    private Logger logger = Logger.getLogger(YahooLogin.class);
    private Session session = new Session();

    public static void main(String[] args) {
        YahooLogin yahooLogin = new YahooLogin();
        yahooLogin.doLogin();
    }

    public YahooLogin() {
    }

    private void doLogin() {
        try {
            // insert your yahoo id
            // as for this example, im using my yahoo ID "dombaganas"
            session.login("dombaganas", "MyYahooPassword", true);
            session.addSessionListener(this);
            Scanner scanner = new Scanner(System.in);

            while (true) {
                System.out.println("please insert your message : ");
                String message = scanner.nextLine();

                // logout if message equals to "bye"
                if (message.equalsIgnoreCase("bye")) {
                    break;
                }
                // send message to targeted yahoo id
                session.sendMessage("TargetYahooID", message);
            }

            // logout from YM
            session.logout();
        } catch (Exception e) {
            logger.error(e, e);

        }
    }

    /*
     *  this is my listener method
     *  it listen for YM message request
     */
    @Override
    public void dispatch(FireEvent fe) {
        ServiceType type = fe.getType();
        SessionEvent sessionEvent = fe.getEvent();

        if (type == ServiceType.MESSAGE) {
            try {
                // log request message
                logger.debug("message from " + sessionEvent.getFrom() + " \nmessage " + sessionEvent.getMessage());

                // give an automatic response
                session.sendMessage(sessionEvent.getFrom(), "hi, you are sending " + sessionEvent.getMessage());
            } catch (Exception e) {
                logger.error(e, e);
            }
        }
    }
}

These are some screenshots related to this application.

To my friend, i hope this tutorial can help you getting started with your assignment. As the wise man once said “Answering one good question is like feeding a hungry person one meal, but teaching them research skills by example is showing them how to grow food for a lifetime.”

YNWA
(I)

ps. if somehow you found a NoClassDefFoundError, such as :
Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
you need to include apache common logging lib into your project classpath.

How to Send Emails With Java Using Gmail Accounts

It’s actually quite simple on how to send emails using java, only need several lines of codes. This is how i do it


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 org.apache.log4j.Logger;

public class MailTestSend {

    private static Logger logger = Logger.getLogger(MailTestSend.class);

    public static void main(String[] args) {
        try {

            // setup the mail server properties
            Properties props = new Properties();
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.starttls.enable", "true");

            // set up the message
            Session session = Session.getInstance(props);

            Message message = new MimeMessage(session);

            // add a TO address
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("xxxxx@gmail.com"));

            // add a multiple CC addresses
            message.setRecipients(Message.RecipientType.CC, InternetAddress.parse("yyyyy@gmail.com,zzzzzz@yahoo.com"));
            
            message.setSubject("Welcome to Java");
            message.setContent("Hi, im testing a new way to send emails via java.", "text/plain");

            Transport transport = session.getTransport("smtp");
            transport.connect("smtp.gmail.com", 587, "yourgmailusername", "yourgmailpassword");
            transport.sendMessage(message, message.getAllRecipients());
            logger.error("successfully send email");
        } catch (Exception e) {            
            logger.error(e, e);
        }
    }
}

Please dont forget to include mail.jar into your project. This is the screenshot of my netbeans libraries and my email inbox.

:-[