======================================
스프링 3.1 이하
======================================
- 리턴을 ResponseEntity 타입으로 함
- 헤더에 캐릭터셋을 설정해서 보냄

@RequestMapping("/ajax")
@ResponseBody
public ResponseEntity handleAJAX() {
   
    ....로직....

    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.add("Content-Type", "text/html; charset=utf-8");
    return new ResponseEntity("한글", responseHeaders, HttpStatus.CREATED);
}



======================================
스프링 3.2 이상
======================================
- @RequestMapping의 produces 옵션이 생겨 좀 더 쉽게 적용 가능함


@RequestMapping(value = "/ajax", produces = "application/json; charset=utf8")
public String handleAJAX() {
   
    ....로직....
  
    return "한글"
}




참고 :
http://softline21c.blogspot.kr/2012/06/springmvc-responsebody.html
http://novafactory.net/archives/3126







http://hangaebal.blogspot.kr/2014/11/spring-spring-responsebody_12.html

public class TestVo {

 //자기 자신을 참조하여 리스트를 리턴하도록 한다.
 private List<TestVo> testList;
 private String key;
 private String name;
 private String phone;
 private Date birth;
 private int age;
 private boolean married;

 
 public List<TestVo> getTestList() {
  return testList;
 }
 public void setTestList(List<TestVo> testList) {
  this.testList = testList;
 }
 public String getKey() {
  return key;
 }
 public void setKey(String key) {
  this.key = key;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getPhone() {
  return phone;
 }
 public void setPhone(String phone) {
  this.phone = phone;
 }
 public Date getBirth() {
  return birth;
 }
 public void setBirth(Date birth) {
  this.birth = birth;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public boolean isMarried() {
  return married;
 }
 public void setMarried(boolean married) {
  this.married = married;
 }
}
 
JSP :
<input name="testList[0].name" />
...
<input name="testList[1].name" />
...


참고 :
http://reikop.tistory.com/16
http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/







http://hangaebal.blogspot.kr/2014/11/spring-modelattribute-arraylist.html

1. 샘플 프로젝트 생성
STS 에서 [File] - [New] - [Spring Template Project] 메뉴를 클릭한 후 Spring MVC Project를 이용해 샘플 프로젝트를 생성한다.
 
2. pom.xml 파일 수정
quartz 관련 모듈을 이용하기 위해서 pom.xml 파일에 관련 라이브러리들 넣는다.
spring-tx, quartz, commons-collections, javax.transaction 4개 넣어줘야한다.

?
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${org.springframework-version}</version>
</dependency>
<!-- Quartz framework and dependencies -->
<dependency>
    <groupId>opensymphony</groupId>
    <artifactId>quartz</artifactId>
    <version>1.6.3</version>
    <scope>compile</scope>
</dependency>
<!-- Quartz 1.6.0 depends on commons collections -->
<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.1</version>
    <scope>runtime</scope>
</dependency>
<!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>jta</artifactId>
    <version>1.1</version>
    <scope>runtime</scope>
</dependency>

 
3. 주기적으로 실행 될 Bean 생성
2개의 Bean을 만든다.
CronQuartz1.java

?
package com.mungchung.sample;
 
import java.text.SimpleDateFormat;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
 
public class CronQuartz1 extends QuartzJobBean{
    @Override
    protected void executeInternal(JobExecutionContext arg0)
            throws JobExecutionException {
        long time = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        System.out.println("Cron trigger 1 (5 second): current time = " + sdf.format(time));
    }
 
}

CronQuartz2.java

?
package com.mungchung.sample;
 
import java.text.SimpleDateFormat;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
 
public class CronQuartz2 extends QuartzJobBean{
    @Override
    protected void executeInternal(JobExecutionContext arg0)
            throws JobExecutionException {
        long time = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        System.out.println("Cron trigger 2 (1 minute): current time = " + sdf.format(time));
    }
}

 
4. quartz Bean과 위에서 생성한 Bean 연동
2개의 Bean이 각각 다른 시간차이로 실행되도록 설정해줄것이다.
CronQuartz1.java - 5초마다 실행
CronQuartz2.java - 1분마다 실행
 
/src/main/webapp/WEB-INF/spring/root-context.xml

?
<!-- 1. Cron 대상이 되는 클래스 정의 -->
<bean id="cronQuartz1" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="com.mungchung.sample.CronQuartz1"/>
</bean>
<bean id="cronQuartz2" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="com.mungchung.sample.CronQuartz2"/>
</bean>
 
<!-- 2. Cron 시간 설정 -->
<bean id="cronTrigger1" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="cronQuartz1"/>
    <property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
<bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="cronQuartz2"/>
    <property name="cronExpression" value="0 0/1 * * * ?"/>
</bean>
 
<!-- 3. Cron 실행 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="cronTrigger1"/>
            <ref bean="cronTrigger2"/>
        </list>
    </property>
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">3</prop>
            <prop key="org.quartz.threadPool.threadPriority">4</prop>
            <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
        </props>
    </property>
</bean>

 
 
Cron Expression
총 7개의 필드 있고 마지막 필드(년도)는 생략 가능하다

 필드이름허용 값 
초(Seconds)0 ~ 59 
분(Minutes)0 ~ 59 
시간(Hours)0 ~ 23
달의 날짜(Day-of-month)1 ~ 31
달(Month) 1 ~ 12 or JAN ~ DEC
주의 날짜(Day-of-week)1 ~ 7 or SUN-SAT
년도(Year) (선택가능) 빈값, 1970 ~ 2099

Cron Expression의 특수문자
Expression설명 예시 
    * 모든 수를 나타냄  
     -값의 사이를 의미* 10-13 * * * *     10,11,12,13분에 동작함 
     ,특정값 지칭* 10,11,13 * * * *      10,11,13분에 동작함
     /값의 증가를 표현* 0/5 * * * *       0분부터 시작해서 5분마다 동작 
     ?특별한 값이 없음을 나타냄(day-of-month, day-of-week 필드만 사용) 
     L마지막 날을 나타냄(day-of-month, day-of-week 필드만 사용) 



6. 실행결과
실행결과를 보면 하나는 5초마다, 다른 하나는 1분마다 Bean이 실행되고 있음을 알수 있다.
 
 
 
출처 :
http://www.mungchung.com/xe/spring/21303


1. STS로 Spring MVC Project 생성 후 접속 확인

- 한글이 깨져서 나오니 home.jsp 파일에
<%@ page language="java" contentType="text/html; charset=UTF-8"  %> 추가


2. pom.xml에 dependency 추가

(버전 확인 - http://mvnrepository.com/)
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.7</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.31</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>



3. root-context.xml에 bean 추가

<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/스키마이름"/>
    <property name="username" value="계정"/>
    <property name="password" value="암호"/>
</bean>

<bean id ="sqlSessionFactory" class= "org.mybatis.spring.SqlSessionFactoryBean" >
    <property name ="dataSource" ref= "dataSource"></property >
    <property name ="configLocation"
        value= "classpath:/mybatis/mybatis-config.xml" >
    </property >
</bean >

<bean id ="transactionManager"
    class= "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
    <property name ="dataSource" ref= "dataSource"></property >
</bean >

<bean id ="sqlSession"
    class= "org.mybatis.spring.SqlSessionTemplate" >
    <constructor-arg ref= "sqlSessionFactory"></constructor-arg >

</bean >



4. mybatis-config.xml 생성

(src/main/resources/mybatis/mybatis-config.xml)

<?xml version="1.0" encoding= "UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd" >

<configuration>
    <mappers >
        <mapper resource ="/mybatis/mapper-sample.xml"/>
    </mappers >
</configuration>



5. mapper-sample.xml 생성

(src/main/resources/mybatis/mapper-sample.xml)
<?xml version="1.0" encoding= "UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace= "userControlMapper" >
    <select id ="selectSample" parameterType="java.util.HashMap" resultType= "java.util.HashMap">
        SELECT *
        FROM TEST_USERS
        WHERE NAME = #{name}
    </select>

    <insert id ="insertTable01" parameterType="java.util.HashMap" >
        INSERT INTO TEST_USERS
        (NAME, EMAIL)
        VALUES
        ( #{name}, #{email} )
    </insert>

</mapper>



6. MySQL에 테스트 table과 data 준비

CREATE TABLE `스키마이름`.`TEST_USERS` (
    `NO` INT NOT NULL AUTO_INCREMENT,
    `NAME` VARCHAR(100) NULL,
    `EMAIL` VARCHAR(100) NULL,
    PRIMARY KEY (`NO`),
    UNIQUE INDEX `NO_UNIQUE` (`NO` ASC));

INSERT INTO TEST_USERS (NAME, EMAIL) VALUES ("han", "han@test.com");



7. HomeController.java 수정

@Controller
public class HomeController {

@Controller
public class HomeController {
    
    // <--- 추가 
    @Autowired
    private SqlSession sqlSession;
    // 추가 --->
    
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    
    /**
    * Simply selects the home view to render by returning its name.
    */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
        
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        
        String formattedDate = dateFormat.format(date);
        
        model.addAttribute("serverTime", formattedDate );
        
        // <--- 추가 
        HashMap<String, String> input = new HashMap<String, String>();
        input.put("name", "han");
        List<HashMap<String, String>> outputs = sqlSession.selectList("userControlMapper.selectSample", input);
        System.out.println(outputs.toString());
        // 추가 --->
        
        return "home";
}
    
}



8. 브라우저로 server 접속 후 Console 출력 확인

- [{NO=1, EMAIL=han@test.com, NAME=han}]


참고 :
http://blog.naver.com/refreshin/150170189512








http://hangaebal.blogspot.kr/2014/08/spring-spring-tool-suitests-mysql.html


1. 스태틱으로 선언하여 클래스 메서드로 만듦
<bean id="객체ID" class="팩토리클래스" factory-method="생성메서드명">


2. 인스턴스 메서드로 만듦
<beam id="팩토리ID" class="팩토리클래스">
(--> static 메서드가 아니라 객체 먼저 생성 필요)

<bean id="객체ID" factory-bean="팩토리ID" factory-method="생성메서드명">


3. AbstractFactoryBean 상속 받아서 클래스 생성
- 단점 : Spring에서만 사용가능
- 장점 : 팩토리 메서드 지정 불필요. 직접 만들어보면 내부 동작 이해에 도움이 됨.

public class TestFactoryBean extends AbstractFactoryBean<Test> {

    @Override
    public Class<?> getObjectType() {
        ...
    }

    @Override
    protected Tire createInstance() throws Exception {
        ...
    }
...
}

<bean id="객체ID" class="팩토리빈클래스">



http://hangaebal.blogspot.kr/2014/06/spring-factory-method-factory-bean.html

*Map과 Properties의 차이
- Map : key나 value로 문자열 및 다른 타입의 객체도 사용 가능
- Properties : Map의 일종이지만, key나 value로 문자열을 다룰 때 주로 사용


*java.util.Properties 타입 :
<props>
 <prop key="키1">값1</prop>
 <prop key="키2">값2</prop>
 ...
</props>


*java.util.Map 타입 :
<map>
 <entry>
  <key>
   <value>키1</value>
  </key>
  <value>값1</value>
 </entry>
 <entry key="키2">
  <ref bean="값2의id"/>
 </entry>
 <entry key="키3" value="값3" />
 <entry key="키4" value-ref="값4의id" />
</map>



http://hangaebal.blogspot.kr/2014/06/spring-map-properties.html

*Eclipse Marketplace 플러그인 준비
- groovy -> Groovy/Grails Tool Suite (GGTS) for ... 설치
- gradle -> Gradle Integration for Eclipse ... 설치


*프로젝트 생성 과정
1. New Gradle Project 생성
(Sample project : Java Quickstart)

2. Gradle 설정 파일 (build.gradle) 수정
apply plugin: 'java'
apply plugin: 'eclipse-wtp'  // WTP(Web Tools Platform) -> 웹 프로젝트로 인식하도록
apply plugin: 'war'

compileJava.options.encoding = 'UTF-8'  // 지정하지 않으면 OS 기본 인코딩으로 간주
sourceCompatibility = 1.7  // 빌드시 해당 버전으로 자바 문법 검사
version = '1.0'

eclipse {
 wtp {
  facet {
   facet name: 'jst.web', version: '3.0' // Servlet Spec Version 지정, 미 지정시 2.4
   facet name: 'jst.java', version: '1.7' // Java Version 지정
  }
 }
}

3. 스프링 라이브러리
www.spring.io > Projects > Spring Framework > Quick Start >
 compile 'org.springframework:spring-context:4.0.5.RELEASE'
를 Gradle 설정파일 dependencies에 복사

4. src 폴더 정리 (4개 폴더 남기고 하위 예제 제거)
src/main/java
src/main/resources
src/test/java
src/test/resources

5. Project> Properties> Java Complier
- Enable project specific settings 체크 해제
  (해당 프로젝트 컴파일러를 별도로 설정하는 옵션)

6. Project> Run As> Gradle Build...
:clean
:cleanEclipse
:eclipse

Run 실행


7. Gradle 프로젝트로 재 설정 (.project 파일)
<nature>org.springsource.ide.eclipse.gradle.core.nature</nature>
- 를 <natures> 태그의 첫번째 항목으로 추가



http://hangaebal.blogspot.kr/2014/06/spring-eclipse-gradle.html

+ Recent posts