Programming     Travel Logs     Life Is Good     Surfing Online     About Me
Seek wealth, not money or status. Wealth is having assets that earn while you sleep. Money is how we transfer time and wealth. Status is your place in the social hierarchy.
-Naval Ravikant
2018-07-22 22:43:18

Copy this link when reproducing:
http://www.casperlee.com/en/y/blog/229

From today on, I'm going to develop a Java web site to replace my current personal web site. It'll probably involve the following techniques:

  • Java Spring MVC
  • MySQL
  • Bootstrap
  • Wechat4j

Just like before, let's take it easy and enjoy a few beautiful photos first.

To setup the development environment, I only need to follow the steps which I used to create the Today In History application. Please check the following links for the details:

http://www.casperlee.com/en/l/blog/88

http://www.casperlee.com/en/l/blog/90

http://www.casperlee.com/en/l/blog/92

http://www.casperlee.com/en/l/blog/179

 

Now, let me ignore the complex details and just list the specific changes for my personal web site.

1. "WebContent\WEB-INF\web.xml":

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>com.casperlee.blog</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/config/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>    
  </servlet>
 
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

2. "WebContent\WEB-INF\config\springmvc-config.xml":

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd     
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd     
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd     
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
         
    <!-- Indicate to scan all controllers in the base-package -->
    <context:component-scan base-package="com.casperlee.blog.controller"/>
    <context:component-scan base-package="com.casperlee.blog.service"/>
    <mvc:annotation-driven/>
    <tx:annotation-driven transaction-manager="transactionManager" />
     
    <!-- Indicate these are static resources -->
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/*.html" location="/"/>
    <mvc:resources mapping="/Images/**" location="/Images/"/>
     
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- With prefix and suffix, we can refer to the view name itself -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
        destroy-method="close">
      <property name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property name="url" value="jdbc:mysql://localhost:3306/BlogDB?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8" />
      <property name="username" value="root" />
      <property name="password" value="password" />
    </bean>
    
    <bean id="hibernateAnnotatedSessionFactory"
      class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="annotatedClasses">
        <list>
          <value>com.casperlee.blog.domain.SiteConfig</value>
        </list>
      </property>
      <property name="hibernateProperties">
        <props>
          <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
          <!--
          <prop key="hibernate.current_session_context_class">thread</prop> 
           -->
          <prop key="hibernate.show_sql">false</prop>
        </props>
      </property>
    </bean>
       
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
      <property name="sessionFactory" ref="hibernateAnnotatedSessionFactory"></property>
    </bean>
    
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
      <property name="sessionFactory" ref="hibernateAnnotatedSessionFactory"></property>
    </bean>
</beans>

3. For convenience, I copied all .jar files from my Today In History project:

4. "src\com\casperlee\blog\controller\BlogController.java":

package com.casperlee.blog.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.casperlee.blog.global.CConstants;
import com.casperlee.blog.service.SiteService;

@Controller
public class BlogController {

	@Autowired
	private SiteService siteService;
	
	@RequestMapping(value = "/")
	public String index(Model model) {
		
		model.addAttribute(CConstants.IMAGE, siteService.getSiteConfig(CConstants.IMAGE));
		model.addAttribute(CConstants.OWNER, siteService.getSiteConfig(CConstants.OWNER));
		model.addAttribute(CConstants.MOTTO, siteService.getSiteConfig(CConstants.MOTTO));
	    return "Index";
	}
}

5. "src\com\casperlee\blog\domain\SiteConfig.java":

package com.casperlee.blog.domain;

import java.io.Serializable;

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

@Entity
@Table(name="SiteConfig")
public class SiteConfig implements Serializable {

	private static final long serialVersionUID = 10000001L;

	@Id
    @Column(name="scId")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="scKey")
	private String key;
	
	@Column(name="scValue")
	private String value;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
	
	@Override
	public String toString() {
		
		return this.getKey() + "=" + this.getValue();
	}
}

6. "src\com\casperlee\blog\global\CConstants.java":

package com.casperlee.blog.global;

public class CConstants {

	// for main page
	public static final String OWNER = "OWNER"; 
	public static final String MOTTO = "MOTTO"; 
	public static final String IMAGE = "IMAGE"; 
}

7. "src\com\casperlee\blog\service\HibernateTemplateHelper.java":

package com.casperlee.blog.service;

import org.hibernate.Session;
import org.springframework.orm.hibernate5.HibernateTemplate;

public class HibernateTemplateHelper {

	private static Session session = null;
	
	public static Session getSession(HibernateTemplate aTemplate) {
		
		if (session != null) {
			
			session.close();
		}
		
		session = aTemplate.getSessionFactory().openSession();
		return session;
	}
}

8. "src\com\casperlee\blog\service\SiteService.java":

package com.casperlee.blog.service;

public interface SiteService {

	public String getSiteConfig(String aKey);
}

9. "src\com\casperlee\blog\service\SiteServiceImpl.java":

package com.casperlee.blog.service;

import java.util.List;

import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.casperlee.blog.domain.SiteConfig;
import com.casperlee.blog.service.HibernateTemplateHelper;

@Service
@Transactional
public class SiteServiceImpl implements SiteService {

	@Autowired
	private HibernateTemplate template;

	@Override
	public String getSiteConfig(String aKey) {
		
		String hql = "from SiteConfig " + "where key = :key ";
		Query<SiteConfig> query = HibernateTemplateHelper.getSession(template).createQuery(
				hql, SiteConfig.class);
		query.setParameter("key", aKey);
		List<SiteConfig> results = query.list();
		if (results.size() > 0) {
			
			return results.get(0).getValue();
		}
		
		return "";
	}
}

10. "WebContent\WEB-INF\jsp\Index.jsp":

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
<title>Insert title here</title>
</head>
<body>
  <div>
    <img alt="" src="${pageContext.request.contextPath}/Images/${IMAGE}">
  </div>
  <div>
    ${OWNER}
  </div>
  <div>
    ${MOTTO}
  </div>
</body>
</html>

11. The SQL scripts for the MySQL database:

create database BlogDB;
use BlogDB;

create table SiteConfig (
scId int(4) primary key not null auto_increment,
scKey varchar(20) not null,
scValue varchar(2000) null
);
alter table SiteConfig convert to character set utf8;
alter table SiteConfig add unique (scKey);

insert into SiteConfig(scKey, scValue) values ("OWNER", "Casper Lee");
insert into SiteConfig(scKey, scValue) values ("MOTTO", "When you affirm big, believe big and pray big, putting faith into action, big things happen.");
insert into SiteConfig(scKey, scValue) values ("IMAGE", "Icons/site.png");

12. Done!