Java Biz App Developer

Aside

This website is my personal memo, and study history.


From what I have seen so far, these are very important things to develop and/or maintain Biz Apps:

  • To be familiar with a Data model can be the most important thing. For Biz Apps, data is (almost) everything. You always need to look at them whenever you got a question from end users.
  • For technical side, SQL skill is extremely important, perhaps even more important than J2EE; As a system get bigger, more data (and tables) you will have to deal with.
  • It is also important to be familiar with Business Flow. Without knowing the business flow, you cannot define a business logic.

In this website, the most examples are based on my experiences. I use a very simple example of Return application process (You purchase something, but want the product to be returned).

In general, a Return transaction is defined as RMA (Return Merchandise Authorization). One transaction (RMA) can have more than one items to return. Each RMA has a type and a reason for returning item(s).

For example, let’s say a transaction #1 (say RMA#1) that has Item A (Camera) and B (Lens). If you order a wrong model by mistake, in this case, the return type is “order by mistake“ and reason is “wrong item“. Therefore, the transaction attributes of RMA#1 are: Item A, with type “order by mistake“ and reason of “wrong item“.

I hope you enjoy reading it. (Go To Index)

Applying Many to Many

many-to-many-header-img1
This is based on this section:


In controller method, it creates a relation ship between RTRN_TP and RTRN_RSN
1. RTRN_RSN object set to HashSet that part of fileds of RTRN_TP
2. RTRN_TP object is saved
many-to-many1
RTRN_RSN of “006”, “010”, and “011” have been bound to RTRN_TP of “01”
many-to-many-data2

@RequestMapping(value = "/cUrlValAttrbSubTpRsn01Jsp", params = "toUnBoundRsnList", method = RequestMethod.POST)
public ModelAndView toUnBoundRsnList(@ModelAttribute("RtrnTpModel") RtrnTpModel tp, ModelMap model, HttpServletRequest req) {

	String tpSelected = (String) req.getSession().getAttribute(CONST.TP_SELECTED.getVal());
	if (CommonBL.hasValue(tpSelected)) {
		List<String> selectedCheckBox = tp.getSelectedCheckBox();
		if (!CommonBL.isEmpty(selectedCheckBox)) {
			for (String code : selectedCheckBox) {
				RTRN_TP_RSN_CMBN tpRsnObj = this.tpRsnSvc.getTpRsnCmbnByHql(tpSelected, code);
				if (tpRsnObj != null) {
					this.tpRsnSvc.delete(tpRsnObj);
				}
			}
		}
	}
	return getMVSubTpRsn01(model, req);
}

Unlike adding the relationship, to delete (un-bound) the relationship, it’s directly deleting the Join Table (RTRN_TP_RSN_CMBN)

Spring + Hibernate Config

hiv-mvc-img

To make your Spring MVC program work with Hibernate, Following files need to be modified:

For more info, see: Spring MVC Config

<beans:bean id="dataSource" 
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <beans:property name="url"      value="jdbc:mysql://localhost:3306/ns201501" />
    <beans:property name="username" value="root" />
    <beans:property name="password" value="nobu" />
</beans:bean>

This is a part of servlet-context.xml. In this case, DB is MySQL.

<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <beans:property name="dataSource" ref="dataSource" />
    <beans:property name="annotatedClasses">
        <beans:list>
            <beans:value>com.ns.spring.model.RMA_HDR</beans:value>
            <beans:value>com.ns.spring.model.RMA_LINE</beans:value>
            <beans:value>com.ns.spring.model.RTRN_TP</beans:value>
            <beans:value>com.ns.spring.model.RTRN_RSN</beans:value>
            <beans:value>com.ns.spring.model.RTRN_TP_RSN</beans:value>
            <beans:value>com.ns.spring.model.RTRN_TP_RSN_CMBN</beans:value>
            <beans:value>com.ns.spring.model.RMA_HDR_STS</beans:value>
            <beans:value>com.ns.spring.model.MDSE</beans:value>
            <beans:value>com.ns.spring.model.RmaLinePk</beans:value>
            <beans:value>com.ns.spring.model.RtrnTpRsnPk</beans:value>
            <beans:value>com.ns.spring.model.ui.RmaHdrModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RmaHdrStsModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RmaLineModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RtrnRsnModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RtrnTpModel</beans:value>
        </beans:list>
    </beans:property>
    <beans:property name="hibernateProperties">
        <beans:props>
            <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
            <beans:prop key="hibernate.show_sql">true</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>

This part defines the classes for CRUD operation. For example, line 7 is the class for Hibernate object (below) represent the table RMA_HDR.

package com.ns.spring.model;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.ns.spring.model.ui.RmaHdrModel;

/**
 * Entity bean with JPA annotations Hibernate provides JPA implementation
 */
@Entity
@Table(name = "RMA_HDR")
public class RMA_HDR {

	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;

	@Column(name = "rma_num")
	private String rmaNum;
	
	@Column(name = "rma_hdr_sts_cd")
	private String rmaHdrStsCd;

	@Column(name = "rtrn_tp_cd")
	private String rtrnTpCd;

	@Column(name = "rtrn_rsn_cd")
	private String rtrnRsnCd;

	@Column(name = "sell_to_cust_cd")
	private String sellToCustCd;

	@OneToMany(mappedBy = "rmaHdr", targetEntity = RMA_LINE.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	private List<RMA_LINE> rmaLines;
	
	public RMA_HDR(){}

	public RMA_HDR(RmaHdrModel hdr) {
		this.id = hdr.getId();
		this.rmaNum = hdr.getRmaNum();
		this.rmaHdrStsCd = hdr.getRmaHdrStsCd();
		this.rtrnTpCd = hdr.getRtrnTpCd();
		this.rtrnRsnCd = hdr.getRtrnRsnCd();
		this.sellToCustCd = hdr.getSellToCustCd();
	}
	// getter and setter
}
CREATE TABLE `rma_hdr` (
	`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
	`rma_num` VARCHAR(20) NOT NULL DEFAULT '',
	`rma_hdr_sts_cd` VARCHAR(20) NULL DEFAULT NULL,
	`rtrn_tp_cd` VARCHAR(20) NOT NULL DEFAULT '',
	`rtrn_rsn_cd` VARCHAR(20) NULL DEFAULT NULL,
	`sell_to_cust_cd` VARCHAR(20) NULL DEFAULT NULL,
	PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=27
;
<!-- Hibernate -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<!-- Apache Commons DBCP -->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
<!-- MySQL -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.9</version>
</dependency>

This is a part of pom.xml. As line 18 to 23, DB is MySQL.

Overview (Dependency Injection)

di-decouple-hdr-img1
DI (Dependency Injection) is one of key features in Spring framework beside (AOP). Spring is the framework that try to decouple the program in many way.

DI is one of ways to decouple the program like a Factory Pattern. In your code, you can GET RID OFnew” statement to create an object.


Example of Dependency:
In your code, the method A need object A1 in order to run it.

Example of Dependency Injection:
Your method A doesn’t have to create a object A1, instead, the object can be injected from somewhere else.

What is good about it?
Your method A can run it without object A1 that makes easier to test it.


There are three ways to do this in Spring framework:

Table of Contents

Aside

Spring MVC
index-icon-mvc1
Spring MVC Config
Submitting a Form
Multiple Row Form Submit
Radio Button and Check Box
Screen Transition (With More than one Controllers)
Select Box Stays Selected

DI (Dependency Injection) and AOP (Aspect Oriented Programming)
index-icon-mvc-aop1
Overview (Dependency Injection)
Dependency Injection: Setter Injection
Dependency Injection: Field Injection
AOP/Aspect-J Overview and Config
Before Advise
After Advise
Around Advise

JPA Hibernate with Spring MVC
hiv-db-bean-img2
Spring + Hibernate Config
Generic DAO
Generic DAO with Custom Method
Generic DAO without Custom Method
HQL and Native SQL in Hibernate
One to Many – Composite Primary Key
Many to Many
Applying Many to Many

Ajax/jQuery with Spring MVC
hdr-sq-img-ajax2
HTML Table Creation
Radio Button Events
Updating an MVC Partial View
Dynamically Creating a Select Box
To Leverage On-Change Dropdown
Auto Complete

Mongo DB, Web Service, Design Pattern, Data Structure, and Bonus
hdr-sq-img-webservice-img2
Mongo DB + Spring MVC
Mongo Repository
Web Service
Optimizing SQL
Static Factory Pattern
Hash Set vs Array List
How To Work on GitHub

AOP/Aspect-J Overview and Config

aop-image-1
(1) Overview

AOP (Aspect Oriented Programming) is one of key features in Spring framework beside (DI).
In AspectJ, which is more flexible and powerful compared to Spring AOP, There are following advices are available: (Source Code)


(2) Configure

<annotation-driven />
<context:component-scan base-package="com.ns.spring" />

<!-- AOP -->
<aop:aspectj-autoproxy>
    <aop:include name="aopBefore" />
    <aop:include name="aopAfter" />
    <aop:include name="aopAround" />
</aop:aspectj-autoproxy>

<!-- "id": Unique ID used by programs to identify the class. Unlike "name"  -->
<!--       it cannot be more than one reference from the same Java object   -->
<!-- "prototype": New instance each time when called                        -->
<!-- "singleton": Single instance per Spring IoC container                  -->
<beans:bean id="aopBefore"  class="com.ns.spring.aop.advise.AspectBefore" scope="prototype"/>
<beans:bean id="aopAfter"   class="com.ns.spring.aop.advise.AspectAfter"  scope="prototype"/>
<beans:bean id="aopAround"  class="com.ns.spring.aop.advise.AspectAround" scope="prototype"/>

   <properties>
.
      <org.aspectj-version>1.7.4</org.aspectj-version>
   </properties>
   <dependencies>
.
.
.
      <!-- AspectJ -->
      <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjrt</artifactId>
         <version>${org.aspectj-version}</version>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjtools</artifactId>
         <version>${aspectj.version}</version>
      </dependency>
      <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjweaver</artifactId>
         <version>1.8.5</version>
      </dependency>
      <dependency>
         <groupId>cglib</groupId>
         <artifactId>cglib</artifactId>
         <version>2.2.2</version>
      </dependency>
   </dependencies>
</project>

MongoDB + Spring MVC

mongodb-img3
NoSQL (Not Only SQL) is growing beside a RDB (Relational database). For example, DynamoDB for Amazon, BigTable for Google, Apollo for Facebook, and so forth. MongoDB is the one of most popular NoSQL DB.


Overview

  • It is said to be “Documente Oriented”, and they call table as “Collection”.
  • Unlike RDB, it does not support JOIN.
  • It Supports an ARRAY in a single record (document).
  • The format looks like JSON object. Therefore, it is good to use with Web Service.
  • Mongo DB is written in C++

This example is Spring MVC with CRUD operation by Mongo DB to demonstrate Web Service. And here is the configuration:
mongo-config

<!-- Mongo DB -->
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-mongodb</artifactId>
	<version>1.5.2.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongo-java-driver</artifactId>
	<version>2.12.4</version>
</dependency>

<dependency>
	<groupId>com.drewnoakes</groupId>
	<artifactId>metadata-extractor</artifactId>
	<version>2.4.0-beta-1</version>
</dependency>

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>ns2015mvcmongo001</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

    <servlet>
        <servlet-name>ns2015</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>ns2015</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

NOTE: At line 16 of web.xml, servlet-name is specified as ns2015. Therefore, servlet context file will be “ns2015-servlet.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:context="http://www.springframework.org/schema/context"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd">

	<context:component-scan base-package="com.ns.spring" />
	 
	<!-- Configuration defining views files -->	 
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	    <property name="prefix">
	        <value>/WEB-INF/jsp/</value>
	    </property>
	    <property name="suffix">
	        <value>.jsp</value>
	    </property>
	</bean>
	 
	<!-- Factory bean that creates the Mongo instance -->
	<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
	    <property name="host" value="localhost" />
	</bean>
	 
	<!-- MongoTemplate for connecting and quering the documents in the database -->
	<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
	     <constructor-arg name="mongo" ref="mongo" />
	     <constructor-arg name="databaseName" value="nsdb" />
	</bean>

	<!-- To scan sub interface for MongoRepository -->
	<mongo:repositories base-package="com.ns.spring" />
</beans>

How To Work on GitHub

github-hdr-img1
This used to be my personal memo to work on GitHub (basic operation), but I also thought it’s good to share to others who might have the same (or similar) problem.

Summary:

  • Creating Repository
  • How to clone the repository
  • How to upload your resource
  • GitHub website to add a SSH key
  • How to generating a SSH key
  • How to delete repository

Web Service

title-image-ws7
In large organization, it can be common to share the data between different systems.

For example, the first system get the “Not authorized transactions” from the other system, and authorize them.

This example shows communicating two different websites through Web Service. The each website uses the different Database. Moreover, they are different kind of database; RDB and NoSQL DB.

They are completely different system but they can share the same data.
webservice-flow-img2

Website 1:

  • URL: http://localhost:8080/ns2015mvcmongo001
  • DB: Mongo DB
  • Send a request to Website 2, and received the response (JSON) and store them in Mongo DB.

Website 2:

  • URL: http://localhost:8080/NS2015V07
  • DB: My SQL
  • Receive the request from Website 1, and get the data from DB (My SQL) and send a response (JSON object) back to Website 1.

2015-06-06_21h23_52


Summarized (Three steps) as two websites are communicating through HTTP:

  1. The Website 1 request the Return transactions (RMAs) which are not “Authorized” to Website 2.
  2. The Website 2 response to the Website 1 with the transactions (in JSON object)
  3. The Website 2 stored them in Mongo DB

From: http://localhost:8080/ns2015mvcmongo001/welcome_01.html
file_MVCController_img2
Controller (Website 1) calls Request to (Website 2):

<input type="submit" value="WebService" name="webService" />

Button in JSP

@RequestMapping(value = "/welcome_01", params = "webService", method = RequestMethod.POST)
public ModelAndView refreshByWebService() {	
	ModelAndView modelAndView = new ModelAndView("welcome_01");	
	List<JSONObject> jsonList = getRmaHdrList();
	saveRma(jsonList);

	List<RMA_HDR> rmaList = rmaRep.findByRma_exclude("auth");
	modelAndView.addObject("rmaList", rmaList);

	return modelAndView;
}

Step 1.1. Calls “getRmaHdrList()” method

private List<JSONObject> getRmaHdrList() {
	String output = getJsonStrByURL(this.url);
	List<JSONObject> list = new ArrayList<JSONObject>();
	try {
		JSONParser parser = new JSONParser();
		Object obj = parser.parse(output);
		JSONArray array = (JSONArray) obj;
		
		for (int i = 0; i < array.size(); i++) {
			JSONObject json = (JSONObject) array.get(i);
			list.add(json);

			Long id = (Long) json.get("id");
			String rmaNum = (String) json.get("rmaNum");
			String rmaHdrStsCd = (String) json.get("rmaHdrStsCd");

			System.out.println("id: " + id);
			System.out.println("rmaNum: " + rmaNum);
			System.out.println("rmaHdrStsCd: " + rmaHdrStsCd);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}		
	return list;
}

Step 1.2. Calls “getJsonStrByURL(String url)” method

private String getJsonStrByURL(String url) {
	Client client = Client.create();
	WebResource response = client.resource("http://localhost:8080/NS2015V07/ns-home/json");
	ClientResponse clientRes = response.accept("application/json").get(ClientResponse.class);
	if (clientRes.getStatus() != 200) {
		throw new RuntimeException("Failed : HTTP error code : " + clientRes.getStatus());
	}
	return clientRes.getEntity(String.class);
}

Step 1.3. Calls Website 2: “http://localhost:8080/NS2015V07/ns-home/json”


From: http://localhost:8080/NS2015V07/ns-home/json
file_WSController_img2
Controller in Website 2 received a request and send a response back to Website 1:

@RequestMapping(value = "/ns-home/json", method = RequestMethod.GET)
public @ResponseBody List<RmaHdrModel> getAll(HttpServletRequest req) {
	List<RmaHdrModel> list = RmaBL.getRmaHdrListWCdTblNm(req);
	List<JSONObject> entities = new ArrayList<JSONObject>();
	for (RmaHdrModel rma : list) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("id", rma.getId());
		jsonObject.put("rmaNum", rma.getRmaNum());
		jsonObject.put("rmaHdrStsCd", rma.getRmaHdrStsCd());
		entities.add(jsonObject);
	}
	return list;
}

Step 2.1. At line 3, get the record from DB (MySQL).
Step 2.2. At line 6 to 10, create a JSON object and being set to a list.
Step 2.3. At line 12, return a list (JSON) as a response to: http://localhost:8080/ns2015mvcmongo001/welcome_01.html

Mongo Repository

mongodb-img3
For CRUD operation in Mongo DB, you have basically two choices:

  • MongoTemplate
  • MongoRepository

And MongoRepository is said to be more advanced compared to MongoTemplate. MongoTemplate provide more pre-defined method than MongoRepository, but MongoRepository is very much like Generic DAO. There are some pre-defined method but you can define your custom methods.

2015-06-05_08h32_07

package com.ns.spring.dao;

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import org.springframework.data.mongodb.repository.Query;
import com.ns.spring.model.RMA_HDR;


@Repository
public interface RmaHdrRepository extends MongoRepository<RMA_HDR, String>{
	
	@Query("{rma_num : ?0}")
	List<RMA_HDR> findByRma_num(String rma_num);

	@Query("{rma_hdr_sts_cd : ?0}")
	List<RMA_HDR> findByRma_hdr_sts_cd(String findByRma_hdr_sts_cd);
	
	@Query("{'rma_hdr_sts_cd' : {$ne : ?0}}")
	List<RMA_HDR> findByRma_exclude(String findByRma_hdr_sts_cd);
	
}

The syntax for MongoDB statements

In MongoDB, the table (RDB) is called “Collection”.
For inquiry: db.”collection name”.find()


Following are some customized generic method defined in RmaHdrRepository.java (line 14 and 20). These will be executed in Mongo DB.

@Query("{rma_num : ?0}")
List<RMA_HDR> findByRma_num(String rma_num);
    /* select * from  rma_hdr where rma_num  = 'RMA00026' */
    db.rma_hdr.find({rma_num : 'RMA00026'})
    

    momgo-select-by-id-img1

@Query("{'rma_hdr_sts_cd' : {$ne : ?0}}")
List<RMA_HDR> findByRma_exclude(String findByRma_hdr_sts_cd);
    /* select * from  rma_hdr where rma_hdr_sts_cd <> 'auth' */
    db.rma_hdr.find({'rma_hdr_sts_cd' : {$ne : 'auth'}})
    

    momgo-select-by-not-eq-img1

NOTE: Equivalent SQL are showing as comments.

List<RMA_HDR> list = rmaRep.findByRma_num(rma_num);
List<RMA_HDR> rmaList = rmaRep.findByRma_exclude("auth");

Called by MVCController.java at line 49, 86 and 96.


Following are non-customized method; Already provided by Mongo Repository

    findAll()
    save(object)
    delete(object)
List<RMA_HDR> rmaList = rmaRep.findAll();
rmaRep.save(rma);
rmaRep.delete(rma);

Called by MVCController.java at line 35, 61, 81, 101, 107.


package com.ns.spring;

import java.util.ArrayList;
import java.util.List;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.ns.spring.dao.RmaHdrRepository;
import com.ns.spring.model.RMA_HDR;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

@Controller
public class MVCController {

	private String url = "http://localhost:8080/NS2015V07/ns-home/json";

	@Autowired
	private RmaHdrRepository rmaRep;

	@RequestMapping(value = "/welcome_01")
	public ModelAndView init01(ModelMap model) {

		ModelAndView modelAndView = new ModelAndView("welcome_01");
		List<RMA_HDR> rmaList = rmaRep.findAll();
		modelAndView.addObject("rmaList", rmaList);

		// mast be match with jsp name to be displayed
		return modelAndView;
	}

	@RequestMapping(value = "/welcome_01", params = "webService", method = RequestMethod.POST)
	public ModelAndView refreshByWebService() {

		ModelAndView modelAndView = new ModelAndView("welcome_01");
		List<JSONObject> jsonList = getRmaHdrList();
		saveRma(jsonList);

		List<RMA_HDR> rmaList = rmaRep.findByRma_exclude("auth");
		modelAndView.addObject("rmaList", rmaList);

		return modelAndView;
	}

	@RequestMapping("/authorize/{rmaNum}")
	public ModelAndView authorizeRma(@PathVariable("rmaNum") String rmaNum) {

		ModelAndView modelAndView = new ModelAndView("welcome_01");
		saveByRmaNum(rmaNum, "auth");

		List<RMA_HDR> rmaList = rmaRep.findAll();
		modelAndView.addObject("rmaList", rmaList);

		return modelAndView;
	}

	private void saveRma(List<JSONObject> jsonList) {

		for (int i = 0; i < jsonList.size(); i++) {
			JSONObject rmaJson = jsonList.get(i);
			Long id = (Long) rmaJson.get("id");
			String rmaNum = (String) rmaJson.get("rmaNum");
			String stsCd = (String) rmaJson.get("rmaHdrStsCd");

			deleteByRmaNum(rmaNum);

			RMA_HDR rma = new RMA_HDR();
			rma.setRma_num(rmaNum);
			rma.setRma_hdr_sts_cd(stsCd);

			rmaRep.save(rma);
		}
	}

	private void deleteByRmaNum(String rma_num) {
		List<RMA_HDR> list = rmaRep.findByRma_num(rma_num);
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				RMA_HDR temp = list.get(i);
				delete(temp);
			}
		}
	}

	private void saveByRmaNum(String rma_num, String stsNm) {
		List<RMA_HDR> list = rmaRep.findByRma_num(rma_num);
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				RMA_HDR temp = list.get(i);
				temp.setRma_hdr_sts_cd(stsNm);
				rmaRep.save(temp);
			}
		}
	}

	private void delete(RMA_HDR obj) {
		rmaRep.delete(obj);
	}

	private List<JSONObject> getRmaHdrList() {
		String output = getJsonStrByURL(this.url);
		List<JSONObject> list = new ArrayList<JSONObject>();
		try {
			JSONParser parser = new JSONParser();
			Object obj = parser.parse(output);
			JSONArray array = (JSONArray) obj;

			for (int i = 0; i < array.size(); i++) {
				JSONObject json = (JSONObject) array.get(i);
				list.add(json);

				Long id = (Long) json.get("id");
				String rmaNum = (String) json.get("rmaNum");
				String rmaHdrStsCd = (String) json.get("rmaHdrStsCd");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	private String getJsonStrByURL(String url) {
		Client client = Client.create();
		WebResource response = client.resource("http://localhost:8080/NS2015V07/ns-home/json");
		ClientResponse clientRes = response.accept("application/json").get(ClientResponse.class);
		if (clientRes.getStatus() != 200) {
			throw new RuntimeException("Failed : HTTP error code : " + clientRes.getStatus());
		}
		return clientRes.getEntity(String.class);
	}
}