/images/profile.png

Oracle + Mybatis ํ™˜๊ฒฝ์—์„œ์˜ Date ๋‹ค๋ฃจ๊ธฐ

์ƒํ™ฉ

  • Oracle, Java 8, mybatis3 ํ™˜๊ฒฝ
  • Date์ปฌ๋Ÿผ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”๋ฐ ์ด๋ฅผ select query๋กœ ์กฐํšŒํ•˜์—ฌ Model์— ๋ฐ”์ธ๋”ฉ ์‹œํ‚ค๊ณ ์ž ํ•จ.
  • ์ฟผ๋ฆฌ์— ์•„๋ฌด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  Date ํ˜•ํƒœ๋กœ Model์— ๋ฐ”์ธ๋”ฉ์„ ํ•˜๋ฉด ์‹œ๋ถ„์ดˆ๊ฐ€ ์—†์–ด์ง„ 2017-01-01 00:00:00 ํ˜•ํƒœ๋กœ ๋‚จ๊ฒŒ๋จ
  • ๊ทธ๋ž˜์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฟผ๋ฆฌ ์ž‘์„ฑํ•  ๋•Œ๋งˆ๋‹ค TO_CHAR๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํฌ๋งท์— ๋งž์ถ”์–ด ํ˜•๋ณ€ํ™˜์„ ์‹œํ‚ค๊ณ  Date ๋˜๋Š” String์œผ๋กœ Model์— ๋ฐ”์ธ๋”ฉ ํ•˜๊ณค ํ–ˆ์Œ.
SELECT
TO_CHAR(reg_ymdt, 'YYYY-MM-DD HH24:MI:SS') AS registDate
FROM
...
  • ์ด๋ ‡๊ฒŒ ํ•˜๋‹ค๋ณด๋‹ˆ query ๋งŒ๋“ค๋•Œ๋งˆ๋‹ค ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์ค˜์•ผํ•˜๊ณ , ์ž์นซ ํฌ๋งทํ˜•์‹์„ ๋‹ค๋ฅด๊ฒŒ ์ ์œผ๋ฉด ์—‰๋šฑํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ฑฐ๋‚˜, Dateํ˜•์„ ๊ทธ๋Œ€๋กœ ๋ฐ›์•„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๋‹ค์‹œ ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •(String to Date)์„ ํ•ด์ค˜์•ผ๋งŒ ํ•จ. .. ๊ท€์ฐจ๋‹ˆ์ฆ˜์˜ ์‹œ์ž‘ : ์‚ฝ์งˆ

1. ์‚ฝ์งˆ์˜ ์‹œ์ž‘

1-1. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.sql.Date ์˜ ๊ฒฝ์šฐ

  • mybatis์—์„œ๋Š” ์ž๋™์ ์œผ๋กœ org.apache.ibatis.type.SqlDateTypeHandler๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ๋จ mybatis 3 ๋ฌธ์„œ ์ฐธ๊ณ 
  • ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ์˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ
@Override
public Date getNullableResult(ResultSet rs, String columnName)  throws SQLException {
	return rs.getDate(columnName);
}
  • java.sql.ResultSet.getDate()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์‹ค์ œ ‘yyyy-mm-dd’ ๋งŒ ๊ฐ€์ ธ์™€ ๋ฆฌํ„ดํ•˜๊ฒŒ๋จ (์—ฌ๊ธฐ์„œ ๋””๋ฒ„๊น… ํ•ด๋ณด๋ฉด rs.getTimestamp(columnName)๊ฐ’์€ ์‹œ๋ถ„์ดˆ๊นŒ์ง€ ๋‹ค ๋“ค์–ด๊ฐ€ ์žˆ์Œ)
  • ๋”ฐ๋ผ์„œ ์‹œ๊ฐ„๊ฐ’์ด ์—†๋Š” yyyy-mm-dd ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด์ด ๋จ

1-2. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.util.Date ์˜ ๊ฒฝ์šฐ

  • mybatis์—์„œ๋Š” ์ž๋™์ ์œผ๋กœ org.apache.ibatis.type.DateOnlyTypeHandler๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ๋จ mybatis 3 ๋ฌธ์„œ ์ฐธ๊ณ 
  • ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ์˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ
@Override
public Date getNullableResult(ResultSet rs, String columnName)  throws SQLException {
	java.sql.Date sqlDate = rs.getDate(columnName);
	if (sqlDate != null) {
		return new java.util.Date(sqlDate.getTime());
	}
	return null;
}
  • ์œ„์˜ org.apache.ibatis.type.SqlDateTypeHandler ๋ณ€ํ™˜์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ ๊ณผ ๊ฐ™์ด yyyy-mm-dd ๋งŒ ๊ฐ€์ ธ์™€์„œ java.sql.Date ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ์ด ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ java.util.Date ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋Š”๋ฐ ์•ž์„œ ์‹œ๊ฐ„๊ฐ’์„ ๋บ€ ์ •๋ณด๋กœ ๋งŒ๋“ค์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ ๋™์ผํ•˜๊ฒŒ yyyy-mm-dd ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด์ด ๋จ

2. ์‚ฝ์งˆ์™„๋ฃŒ, ํ•ด๊ฒฐ์˜ ์‹œ์ž‘

  • ์˜ค๋ผํด + mybatis ํ™˜๊ฒฝ์—์„œ Dateํƒ€์ž…์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ๋Š” ํƒ€์ž…ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค๋Š”๊ฑธ ์•Œ๊ฒŒ๋จ.

2-1. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.sql.Date ์˜ ๊ฒฝ์šฐ

  • ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋“ฑ๋ก์„ ์‹œ์ผœ์ค€๋‹ค.
  • mybatis-config.xml
<typeHandlers>
	<typeHandler handler="com.naver.dbill.admin.common.handler.CustomDateHandler"/>
</typeHandlers>
  • CustomDateHandler.java
...
import java.sql.Date;
...
public class CustomDateHandler extends BaseTypeHandler<Date> {
	...
	@Override
	public Date getNullableResult(ResultSet rs, String columnName) throws SQLException {
		Timestamp sqlTimestamp = rs.getTimestamp(columnName);
		if (sqlTimestamp != null) {
			return new Date(sqlTimestamp.getTime());
		}
		return null;
	}
	...
}
  • ์œ„ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‹œ๋ถ„์ดˆ ๊ฐ’์ด ์žˆ๋Š” ์™„์ „ํ•œ Date ํ˜•ํƒœ๋ฅผ ๋ณผ์ˆ˜ ์žˆ๋‹ค.

2-2. ์˜ค๋ผํด์˜ DATEํ˜• โ†’ java.util.Date ์˜ ๊ฒฝ์šฐ

  • ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด ๋“ฑ๋ก์„ ์‹œ์ผœ์ค€๋‹ค.
  • ๋‹จ, mybatis 3 ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด java.sql.Date ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๊ธฐ๋ณธ์œผ๋กœ ์„ค์ •๋œ typeHandler๊ฐ€ JDBC์— ๋”ฐ๋ผ 3๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ž‘์„ฑํ•œ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์ž๋ฐ”ํƒ€์ž… ๊ณผ JDBCํƒ€์ž… ์„ ์ ์–ด์ค˜์•ผ ์ •์ƒ์ ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋˜์–ด ํ•ด๋‹น ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.
  • mybatis-config.xml
<typeHandlers>
		<typeHandler handler="com.naver.dbill.admin.common.handler.CustomDateHandler" javaType="java.util.Date" jdbcType="DATE"/>
</typeHandlers>
  • CustomDateHandler.java ๋Š” ์œ„์™€ ๋™์ผํ•˜๋‹ค. ( import java.util.Date; ์‚ฌ์šฉ์œผ๋กœ ๋ณ€๊ฒฝ )

์‚ฝ์งˆํ•˜๋ฉฐ ์•Œ๊ฒŒ๋œ ๋ณด๋„ˆ์Šค ์ง€์‹

  • java.sql.Date ๋Š” java.util.Date ์„ ์ƒ์†๋ฐ›์•˜๋‹ค.
public class Date extends java.util.Date {
}
  • ๊ฒ€์ƒ‰์„ ํ•˜๋‹ค๋ณด๋ฉด ์•Œ์ˆ˜์žˆ๊ฒ ์ง€๋งŒ java.sql.Date ๋Š” JDBC๋“ฑ์„ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ ํ•ฉํ•˜๊ณ , java.util.Date ์€ ๋ณด๋‹ค ๋ฒ”์šฉ์ ์ธ ๋‚ ์งœ๋‚˜ ์‹œ๊ฐ์ •๋ณด๋ฅผ ๋‹ค๋ฃฐ๋•Œ ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.
  • toString ๋ฉ”์†Œ๋“œ์˜ ๋ฆฌํ„ด Format ํ˜•ํƒœ
    • java.sql.Date : yyyy-mm-dd
    • java.util.Date : EEE MMM dd HH:mm:ss zzz yyyy
  • mybatis ์—์„œ ํ˜•๋ณ€ํ™˜์€ mybatis 3 ๋ฌธ์„œ์— ๋‚˜์™€์žˆ๋Š” ์ž๋ฐ”ํƒ€์ž…๊ณผ JDBCํƒ€์ž…์ด ์ผ์น˜ํ•  ๊ฒฝ์šฐ์— ํ•ด๋‹น ํƒ€์ž… ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

์ •์ƒํ˜ ๋‹˜ ์กฐ์–ธ ( http://d2.naver.com/helloworld/645609 ์ž‘์„ฑํ•˜์‹ ๋ถ„ )

  • Oracle์˜ JDBC ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์˜ˆ์ƒ ๋ฐ–์œผ๋กœ ๋™์ž‘ํ•˜๋„ค์š”. Oracle์˜ DATE ํƒ€์ž…๋„ ๋ฌธ์„œ๋ฅผ ๋ณด๋‹ˆ ์‹œ๋ถ„์ดˆ๊นŒ์ง€ ์ €์žฅํ•˜๊ฒŒ ๋˜์–ด ์žˆ๋Š”๋ฐ, Oracle JDBC ๊ตฌํ˜„์ฒด๊ฐ€ DATE ํƒ€์ž…์˜ ์ฒ ํ•™์„ ์˜คํ•ดํ•œ๊ฒŒ ์•„๋‹Œ๊ฐ€ํ•˜๋Š” ์ƒ๊ฐ๋„ ๋“ญ๋‹ˆ๋‹ค.
  • ์ฐธ๊ณ ๋กœ java.sql.Date, java.sql.TimeStamp๋Š” ์ž˜๋ชป๋œ ์„ค๊ณ„๋ผ๋Š” ๋น„ํŒ์ด ๋งŽ์Šต๋‹ˆ๋‹ค.
  • ์ €๋„ Java์˜ ๋‚ ์งœ์™€ ์‹œ๊ฐ„ API ๋ผ๋Š” ๊ธ€์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ ์€ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

java.sql.Date ํด๋ž˜์Šค๋Š” ์ƒ์œ„ ํด๋ž˜์Šค์ธ java.util.Date ํด๋ž˜์Šค์™€ ์ด๋ฆ„์ด ๊ฐ™๋‹ค. ์ด ํด๋ž˜์Šค๋ฅผ ๋‘๊ณ  Java ํ”Œ๋žซํผ ์„ค๊ณ„์ž๋Š” ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ง€์œผ๋ฉด์„œ ๊นœ๋นก ์กด ๋“ฏํ•˜๋‹ค๋Š” ์กฐ๋กฑ๊นŒ์ง€ ๋‚˜์™”๋‹ค.[24]

์Šคํ”„๋งํ™˜๊ฒฝ์—์„œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ด€๋ จ ์ •๋ฆฌ

์ผ๋ฐ˜์ ์ธ ์›น ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ์—์„œ๋Š” Controller๋ ˆ๋ฒจ์—์„œ ์‘๋‹ต์„ ๋ฐ›๊ณ  ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌ ํ›„์— ๋‹ค์‹œ View๋ ˆ๋ฒจ๋กœ ๋„˜์–ด๊ฐ€๋Š”๊ฒŒ ํ†ต์ƒ์ ์ธ ํ๋ฆ„์ด๋‹ค. ์ด ๋ถ€๋ถ„์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ด€๋ จํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

httpServletRequest.getParameter()

์•„๋ž˜์†Œ์Šค์ฒ˜๋Ÿผ HttpServletRequest์˜ getParameter() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

@RequestMapping("/")
public String home(HttpServletRequest httpServletRequest) {
    String id = httpServletRequest.getParameter("id");

    return "home";
}

@RequestParam

๋˜๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” @RequestParam ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ์ˆ˜ ์žˆ๋‹ค. ์šฐ์„ , ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์˜ ์˜ต์…˜๊ฐ’๋“ค์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ํ™•์ธํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋Š”๊ฒŒ ์ข‹์„๋“ฏ ์‹ถ๋‹ค. API๋ฌธ์„œ 4.3.6 ๊ธฐ์ค€

์ด๋ฆ„ํƒ€์ž…์„ค๋ช…
name, value (Alias for name)StringํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„
requiredbooleanํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•„์ˆ˜์ธ์ง€ ์—ฌ๋ถ€, ๊ธฐ๋ณธ๊ฐ’์€ true
defaultValueStringํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ธฐ๋ณธ๊ฐ’

์œ„ ์˜ต์…˜๊ฐ’๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์— ์ ์šฉํ•ด๋ณด๋ฉด ์•„๋ž˜ ์†Œ์Šค์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ์ด๋ ‡๊ฒŒ reqeust์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ์ˆ˜ ์žˆ๋‹ค.

@RequestMapping("/")
public String home(@RequestParam(value="id", defaultValue="false") String id) {
    return "home";
}

์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๊ฒŒ๋˜๋ฉด ์ž์นซ ์ž˜๋ชปํ•˜๋‹ค๊ฐ„ ์—๋Ÿฌ๋ฅผ ๋งŒ๋‚ ์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ required๊ฐ’์„ true๋กœ ํ•ด๋†“๊ณ  (ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •) ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด HTTP 400 ์—๋Ÿฌ๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋‹ˆ ๊ฐ ์˜ต์…˜๋“ค์„ ์ •ํ™•ํžˆ ํ™•์ธํ•˜๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค. ๋ฌผ๋ก  ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋ฉ”์†Œ๋“œ์—์„œ ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ฐ”๋กœ ๋ฐ›์„์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ ๋ฐ›์„ ๊ฒฝ์šฐ๋Š” ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์ด false๋กœ ์„ค์ •์ด ๋˜๊ณ  ๋ณ€์ˆ˜๋ช…๊ณผ ๋™์ผํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ๋ฐ›์„์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉฐ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์„ ํ• ์ˆ˜๋Š” ์—†๋‹ค. ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด๋ผ์„œ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋งž์ถฐ ์‚ฌ์šฉํ•˜๋ฉด ๋ ๋“ฏ ํ•˜๋‹ค.

@RequestMapping("/")
public String home(String id) {
    return "home";
}

@RequestBody

@RequestBody์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ POSTํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›๋Š” ๊ตฌ์กฐ์—ฌ์•ผ๋งŒ ํ•œ๋‹ค. ์ด๋ฅผํ…Œ๋ฉด JSON ์ด๋‚˜ XML๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํ•œ messageConverter๋กœ ์ฝ์„๋•Œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, POJOํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ ์ „์ฒด๋กœ ๋ฐ›์„๊ฒฝ์šฐ์— ์‚ฌ์šฉ๋œ๋‹ค. ๋‹จ, ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„ ๊ฒฝ์šฐ ๋ณ„๋„์˜ ์ถ”๊ฐ€ ์„ค์ •(POJO ์˜ get/set ์ด๋‚˜ json/xml ๋“ฑ์˜ messageConverter ๋“ฑ)์„ ํ•ด์ค˜์•ผ ์ ์ ˆํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„์ˆ˜๊ฐ€ ์žˆ๋‹ค.

@PostMapping("/")
public String home(@ReqeustBody Student student) {
    return "home";
}

@ModelAttribute

@RequestParam๊ณผ ๋น„์Šทํ•œ๋ฐ 1:1๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„๊ฒฝ์šฐ๋Š” @RequestParam๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋„๋ฉ”์ธ์ด๋‚˜ ์˜ค๋ธŒ์ ํŠธ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„ ๊ฒฝ์šฐ๋Š” @ModelAttribute์œผ๋กœ ๋ฐ›์„์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒ€์ฆ(Validation)์ž‘์—…์„ ์ถ”๊ฐ€๋กœ ํ• ์ˆ˜ ์žˆ๋Š”๋ฐ ์˜ˆ๋กœ๋“ค์–ด null์ด๋ผ๋˜์ง€, ๊ฐ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋งˆ๋‹ค valid์˜ต์…˜์„ ์ค„์ˆ˜๊ฐ€ ์žˆ๊ณ  ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๊ฐ€ ๋‚  ๊ฒฝ์šฐ BindException ์ด ๋ฐœ์ƒํ•œ๋‹ค.

Spring command ๊ฐ์ฒด

์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์€ ์ •๋ณด์— ๋Œ€ํ•ด์„œ๋Š” view ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์˜ˆ๋กœ ๋“ค์–ด ์•„๋ž˜๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์ด๋ ‡๊ฒŒ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ๊ตฌ์„ฑ๋˜์–ด์žˆ๊ณ 

/images/spring-parameter/spring-parameter-1.jpg

์ด๋ ‡๊ฒŒ ๋ชจ๋ธ์ด ๊ตฌ์„ฑ๋˜์–ด์žˆ์„๋•Œ

/images/spring-parameter/spring-parameter-2.jpg

view ์—์„œ ์ด๋Ÿฐ์‹์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

/images/spring-parameter/spring-parameter-3.jpg

์ด๋•Œ /student?name=taetaetae&age=32&address=green-factory๋กœ ํ˜ธ์ถœ์„ ํ•ด๋ณด๋ฉด ๊ตฌ์ง€ Model์— ๊ฐ’์„ ์…‹ํŒ…ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •๋ณด๋ฅผ ์ฝ์„์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

/images/spring-parameter/spring-parameter-4.jpg

๋งˆ์น˜๋ฉฐ

์Šคํ”„๋ง์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•์€ ์ƒ๋‹นํžˆ ๋‹ค์–‘ํ•˜๋‹ค. ์ด๊ฒŒ ์ •๋‹ต์ด๋‹ค ์ •์˜ํ• ์ˆ˜ ์—†์„์ •๋„๋กœ. ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋งž๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„์•ผ ํ•˜๊ฒ ๊ณ , ๊ฐ ๋ฐฉ๋ฒ•์— ์žฅ/๋‹จ์ ์„ ์ตœ๋Œ€ํ•œ ์‚ด๋ ค์„œ ์ข€๋” ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ• ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ฒ ๋‹ค.

๋ฒŒ์จ 3์›”, ๋‹ค์‹œ ์ผ์–ด์„œ์•ผํ•  ๋•Œ

๋ฒŒ์จ 3์›”์ด๋‹ค. ๋ญํ•˜๋‚˜ ์ œ๋Œ€๋กœ ํ•œ๊ฒƒ๋„ ์—†๋Š”๋ฐ ์‹œ๊ฐ„์€ ์•ผ์†ํ•˜๊ฒŒ๋„ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ์ง€๋‚˜๊ฐ€๊ณ  ์žˆ๋‹ค. ์˜ค๋žœ๋งŒ์— ๋™๊ธฐํ˜•์„ ๋งŒ๋‚ฌ๋‹ค. ์‹ ์ž…์‚ฌ์›์ด ๋˜๊ธฐ ์ „ ์—ฐ์Šต์ƒ(?)์‹œ์ ˆ ๋™๊ฑฐ๋™๋ฝํ•˜๋ฉฐ ๊ฐœ๋ฐœ์— ๋Œ€ํ•ด ๊ณ ๊ตฐ๋ถ„ํˆฌ ํ•˜๋˜ ์‚ฌ์ด์ธ์ง€๋ผ. ์˜ค๋žœ๋งŒ์— ๋งŒ๋‚˜๋„ ์„œ๋กœ ์ด์•ผ๊ธฐ ํ•˜๊ณ ์ž ํ•˜๋Š” ์ฃผ์ œ๋Š” ์–ธ์ œ๋‚˜ ๋™์ผํ•˜๋‹ค. ๊ฐœ๋ฐœ์ž๋กœ์„œ์˜ ์‚ถ ์ด๋Ÿฐ์ €๋Ÿฐ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋ฉฐ ๋‹ค์‹œ ๋‚˜๋ฅผ ๋Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ๋‚ด ๋…ธ๋ ฅ์— ์˜ํ•ด, ์•„๋‹ˆ๋ฉด ์šด์ด ์ข‹์•„ ์ง€๊ธˆ ๋‹ค๋‹ˆ๊ณ ์žˆ๋Š” ํšŒ์‚ฌ์— ๋“ค์–ด์˜จ ์ดํ›„๋กœ ์˜ˆ์ „๋งŒํผ์˜ ์—ด์ •์€ ์˜จ๋ฐ๊ฐ„๋ฐ ์—†์œผ๋ฉฐ, ๊ทธ๋งŒํผ ๊ฐ„์ ˆํ•˜์ง€๋„ ์•Š๊ณ  ์น˜์—ดํ•˜์ง€๋„ ์•Š๋Š” ๋‚ด ์ž์‹ ์ด ๋„ˆ๋ฌด ๋ฏธ์•ˆํ•˜๊ณ  ์ชฝํŒ”๋ฆด์ •๋„๋กœ ํ•œ์‹ฌํ•˜๊ธฐ ๊ทธ์ง€ ์—†์—ˆ๋‹ค. ๋ฌด์—‡๋•Œ๋ฌธ์ผ๊นŒ, ๋„๋Œ€์ฒด ์™œ ์ด๋ ‡๊ฒŒ ์•ˆ์ผํ•ด์กŒ๊ณ  ์ ๊ทน์ ์ด์ง€ ๋ชปํ•˜๊ฒŒ ๋˜์—ˆ์„๊นŒ. ๊ทธ ์งˆ๋ฌธ์— ๋Œ€ํ•œ ์ •๋‹ต์€ ์ด๊ฒƒ์ด๋‹ค ๋ผ๊ณ  ์ •์˜๋ฅผ ํ• ์ˆ˜๋Š” ์—†๊ฒ ์ง€๋งŒ ํ™•์‹คํ•œ๊ฑด, ํ˜„์žฌ ๋‚ด ์ƒํ™ฉ์— ์•ˆ์ฃผํ•˜๊ณ  ํƒ€ํ˜‘ํ•˜๋ คํ•˜๋Š” ๋งˆ์Œ๊ฐ€์ง์ด ์ƒ๊ฒผ๋‹ค๋Š”๊ฑด ํšŒํ”ผํ• ์ˆ˜ ์—†์„์ •๋„๋กœ ๋‚˜๋„ ์ •๋ง ๋งŽ์ด ๋ณ€ํ•ด๋ฒ„๋ฆฐ๊ฒƒ ๊ฐ™๋‹ค. ๋ฌผ๋ก  ์ง€๊ธˆ ์ƒํ™ฉ์ด ์ž˜๋ชป๋˜์—ˆ๋‹ค๋Š”๊ฑด ์•„๋‹ˆ์ง€๋งŒ ๋‚ด ์ง์—… ํŠน์„ฑ์ƒ ๋Š์ž„์—†์ด ๋…ธ๋ ฅํ•˜๊ณ  ๋„์ „ํ•˜๋ฉฐ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ธ๋ฐ ์ง€๊ธˆ ๋‚œ ํ‡ด๊ทผํ•˜๊ณ  ์ง‘์—๊ฐ€๋ฉด ์‰ฌ๊ณ ์‹ถ๊ณ  ์ž๊ธฐ ๋ฐ”์˜๊ณ  ๋‹ค์Œ๋‚  ๋Šฆ์ž ์ž๊ณ … ๊ณ„์†๋œ ์ƒํ™œํŒจํ„ด์— ์ –์–ด ์‚ฌ๋Š”๊ฒƒ ๊ฐ™๋‹ค. ์ผ๋‹จ ๋…์„œ์ข€ ๋งŽ์ด ํ•ด์•ผ๊ฒŸ๋‹ค. ํšŒ์‚ฌ์—, ์ง‘์— ์Œ“์ธ ์ฑ…๋งŒ ๋ฒŒ์จ ๋ช‡๊ถŒ์ธ์ง€… ๊ธฐ๋ณธ์ด ๋˜๋Š” ์ „๊ณต์„œ์  ํ•˜๋‚˜ ์ •ํ•˜๊ณ  ๋๊นŒ์ง€ ์™„๋…ํ•ด๋ณด์ž. ๊ทธ๊ฒŒ ์ž๋ฐ”๋“  ์Šคํ”„๋ง์ด๋“ , ์ตœ์‹  ์‹ ๊ธฐ์ˆ ๋ณด๋‹ค ๊ธฐ๋ณธ์ด ํƒ„ํƒ„ํ•ด์ ธ์•ผ ํ•˜๋Š”๊ฑด ๋ฐฑ๋ฒˆ ์ฒœ๋ฒˆ ๋งํ•ด๋„ ๋‹น์—ฐํ•˜๊ธฐ์—.

๋‹ค์‹œ ์ •์‹ ์ฐจ๋ฆฌ์ž. ์˜ค๋Š˜ ๊ฑท์ง€ ์•Š์œผ๋ฉด ๋‚ด์ผ์€ ๋‹ฌ๋ ค์•ผ ํ•œ๋‹ค๊ณ  ๋ˆ„๊ตฐ๊ฐ€ ๊ทธ๋žฌ๋“ฏ..

github api ์‚ฌ์šฉ๋ฐฉ๋ฒ•

github ์—์„œ๋Š” ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์˜ ์ „๋ฐ˜์ ์ธ ์ƒํ™ฉ์— ๋Œ€ํ•ด ๋‹ค์–‘ํ•œ API๋ฅผ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ๊ทธ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค.

Personal access tokens ๋ฐœ๊ธ‰

์šฐ์„  ์ •์ƒ์ ์ธ API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Personal access tokens๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์•„์•ผ ํ•œ๋‹ค. github ์ดˆ๊ธฐํ™”๋ฉด > ์šฐ์ธก์ƒ๋‹จ ํ”„๋กœํ•„์‚ฌ์ง„ ํด๋ฆญ > setting > Personal access tokens ์— ๋“ค์–ด๊ฐ€ ํ† ํฐ์„ ์ƒ์„ฑ์„ ํ•œ๋‹ค. ํ•ด๋‹น ํ† ํฐ์˜ ํ—ˆ์šฉ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•œ๋’ค ์ƒ์„ฑ์„ ํ•˜๋ฉด ๋งŒ๋“ค์–ด ์ง€๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ๋ฐœ๊ธ‰๋˜๋Š” ๋ฌธ์ž์—ด์€ ๋”ฐ๋กœ ๋ณด๊ด€ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค. (๋‚˜์ค‘์— ๋‹ค์‹œ ํ™•์ธํ•˜๋ ค๋ฉด ์ƒˆ๋กœ ์žฌ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๋ง๊ณ ๋Š” ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ๋งŒ๋“ค๋•Œ ๋ฉ”๋ชจํ•ด ๋‘๋Š”๊ฒŒ ์ข‹๋‹ค.) ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ์™„๋ฃŒ. /images/github-api/github_access_tokens.png

API ์‚ฌ์šฉ๋ฐฉ๋ฒ•

๊ถŒํ•œ์ด ์—†๋Š” Repository ์˜ ๋‚ด์šฉ์„ ํ™•์ธํ• ์ˆ˜ ์—†๋“ฏ์ด github์—์„œ ์ œ๊ณตํ•˜๋Š” API๋˜ํ•œ ๊ถŒํ•œ์ด ์žˆ๋Š” Repository์— ๋Œ€ํ•ด์„œ๋งŒ API๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์œ„์—์„œ ๋ฐœ๊ธ‰ํ•œ token ์„ ๊ถŒํ•œ ์ฒดํฌํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์„์ˆ˜ ์žˆ๊ฒ ์œผ๋‚˜ ๋‚˜๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ—ค๋”์— ํฌํ•จ์‹œ์ผœ์„œ ์ผ๋ฐ˜ GET ํ˜ธ์ถœ์„ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•˜์˜€๋‹ค. ์œˆ๋„์šฐ ํ™˜๊ฒฝ์—์„œ๋Š” ํ—ค๋” ์…‹ํŒ…ํ•˜๊ณ  ํ˜ธ์ถœํ•˜๋Š”๊ฒŒ ์กฐ๊ธˆ ์–ด๋ ค์šธ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ด๋Ÿฌํ•œ ๋ถ€๋ถ„์„ ์„ค์ •ํ• ์ˆ˜ ์žˆ๋Š” Postman์ด๋ผ๋Š” ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํ˜ธ์ถœ์„ ํ•ด๋ณธ๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ url์€ https://api.github.com/์œผ๋กœ ์„ค์ •ํ•˜๊ณ  HeadersํŒŒ๋ผ๋ฏธํ„ฐ์— Authorization๋ผ๋Š” key์— value๋ฅผ ์œ„์—์„œ ๋ฐœ๊ธ‰๋ฐ›์•˜๋˜ token์„ ์ด์šฉํ•˜์—ฌ token abcd~~์‹์œผ๋กœ ์ž…๋ ฅํ•ด์ค€๋‹ค์Œ send๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์ฃผ๋ฉด ์‘๋‹ต์„ ๋ฐ›์„์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ, ์•„๋ž˜ ๊ทธ๋ฆผ์€ ์ œ๊ณตํ•˜๋Š” api์˜ ๋ชจ๋“  url์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

/images/github-api/github_api_call_1.png

์•„๋ž˜์• ์„œ๋Š” ์œ„์—์„œ ํ™•์ธ๋œ api url์„ ํ™œ์šฉํ•˜์—ฌ ๋‚ด๊ฐ€ ๊ถŒํ•œ์ด ์žˆ๋Š” ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ ๋‚ด์—์„œ ํ™•์ธํ• ์ˆ˜์žˆ๋Š” ์ •๋ณด์— ๋Œ€ํ•œ API๋ฅผ ํ˜ธ์ถœํ•ด๋ณด์•˜๋‹ค.

/images/github-api/github_api_call_2.png

API ํ˜ธ์ถœ์‹œ ๊ฐ€์žฅ ๋ณดํŽธํ™”๋˜์–ด์žˆ๋Š”(?) ์ŠคํŒฉ์ธ JSON์œผ๋กœ ์‘๋‹ต์ด ๋‚ด๋ ค์˜ค๊ธฐ๋•Œ๋ฌธ์— ์–ด๋– ํ•œ ํ™˜๊ฒฝ์—์„œ๋„ ์ถฉ๋ถ„ํžˆ ํ™œ์šฉํ• ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค. ๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ํŒ€ ๋‚ด์—์„œ ํ•˜๋‚˜์˜ Organizations๋‚ด์— ์—ฌ๋Ÿฌ Repository๊ฐ€ ์žˆ๋Š”๋ฐ ๊ฐ๊ฐ์˜ PullRequest์— ๋Œ€ํ•ด ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์ผ์ผํžˆ ๋‹ค ์ฐพ์•„๋ณด๊ธฐ ๊ท€์ฐฎ์•„ github-api๋ฅผ ํ™œ์šฉํ•ด open๋œ PullRequest๊ฐ€ ์žˆ์œผ๋ฉด ์•Œ๋ฆผ์„ ์ฃผ๋Š” ๊ฑธ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.

๋ฆฌ๋ˆ…์Šค์ƒ์—์„œ json ํŒŒ์‹ฑ

๋ฆฌ๋ˆ…์Šค ์ƒ์—์„œ jsonํ˜•ํƒœ์˜ String ์„ ํŒŒ์‹ฑํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์•„๋ž˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋Š”๊ฒƒ์„ ์ถ”์ฒœํ•ด๋ณธ๋‹ค.

jq

์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ๋„ˆ๋ฌด๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜๋‹ค.

  • ์ž์‹ ์˜ ์‹œ์Šคํ…œ์— ๋งž๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋ฐ›๊ณ 
(32-bit system)
$ wget http://stedolan.github.io/jq/download/linux32/jq
(64-bit system)
$ wget http://stedolan.github.io/jq/download/linux64/jq
  • ์‹คํ–‰ ๊ถŒํ•œ์„ ์„ค์ •ํ•ด ์ค€ ๋’ค
chmod +x ./jq
  • root ๊ถŒํ•œ์œผ๋กœ ํ•ด๋‹น ํŒŒ์ผ์„ ์ด๋™์‹œํ‚จ๋‹ค.
sudo cp jq /usr/bin
  • ์‹คํ–‰์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•œ๋‹ค. Json String ์ด ์•„๋ž˜์™€ ๊ฐ™์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„๋•Œ
{
"name": "Google",
"location":
  {
    "street": "1600 Amphitheatre Parkway",
    "city": "Mountain View",
    "state": "California",
    "country": "US"
  },
"employees":
  [
    {
      "name": "Michael",
      "division": "Engineering"
    },
    {
      "name": "Laura",
      "division": "HR"
    },
    {
      "name": "Elise",
      "division": "Marketing"
    }
  ]
}

์‹ค์ œ ์‚ฌ์šฉ๊ณผ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋ฃจ์–ด ์ง„๋‹ค.

$ cat json.txt | jq '.name'
"Google"

$ cat json.txt | jq '.location.city'
"Mountain View"

$ cat json.txt | jq '.employees[0].name'
"Michael"

$ cat json.txt | jq '.location | {street, city}'
{
  "city": "Mountain View",
  "street": "1600 Amphitheatre Parkway"
}

๋ณด๋‹ค ์ž์„ธํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ๊ณต์‹ํ™ˆํŽ˜์ด์ง€( https://stedolan.github.io/jq/ )๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์ข‹์„๋“ฏ ํ•˜๋‹ค.

eclipse์—์„œ spring-boot๋กœ web ๋งŒ๋“ค๊ธฐ

Spring ํ™˜๊ฒฝ์—์„œ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋ฉด pom.xml ์— ์ด๋Ÿฐ์ €๋Ÿฐ ์„ค์ •๋“ค์„ ์ ์–ด์ค˜์•ผ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์ˆ˜๊ณ (?)๋ฅผ ๋œ์–ด์ค„์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ค‘์— ํ•œ๊ฐ€์ง€๊ฐ€ ๋ฐ”๋กœ Spring Boot๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ธ๋ฐ, ์ดํด๋ฆฝ์Šค ํ™˜๊ฒฝ์—์„œ ๋งŒ๋“œ๋Š” ๋ฒ•์„ ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค.

new > Maven Project

๋นˆ Maven Project ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๋‹ˆ ์ƒ๋žตํ•˜๊ณ … ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด pom.xml ์€ ์•„๋ž˜์ฒ˜๋Ÿผ ์•„์ฃผ ๊น”๋”ํ•œ(?)์ƒํƒœ๋กœ ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋œ๋‹ค.

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>boot</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</project>

๊ทธ๋Ÿฌ๋ฉด ์ด ๋น„์–ด์žˆ๋Š” pom.xml ์— Spring-Boot ์— ํ•„์š”ํ•œ ์„ค์ •๋“ค์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ธฐ๋กœ ํ•œ๋‹ค.

<parent> <!--boot์˜ ์Šคํƒ€ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •-->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
    <relativePath />
</parent>

<dependencies>
    <dependency> <!--boot์—์„œ ์Šคํƒ€ํ„ฐํŒจํ‚ค์ง€๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฒƒ๋“ค์ค‘์— web ์„ค์ • ๋ถ€๋ถ„ -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

๊ทธ๋‹ค์Œ ์ž„์˜์˜ java ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ๊ฑฐ๊ธฐ์— ์•„๋ž˜์ฒ˜๋Ÿผ ์„ค์ •ํ•˜๋ฉด ๋

@SpringBootApplication // @Configuration + @EnableAutoConfiguration + @ComponentScan ๋“ค์˜ ์ข…ํ•ฉ ์–ด๋…ธํ…Œ์ด์…˜
public class TestApplication{
    public static void main(String[] args) throws Exception {
        SpringApplication.run(TestApplication.class, args);
    }
}

Spring Boot ์—์„œ๋Š” ๋‚ด์žฅWAS๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— main ๋ฉ”์†Œ๋“œ์—์„œ ์šฐํด๋ฆญํ›„ run AS โ†’ Spring Boot App ์„ ์„ ํƒํ•ด์ฃผ๋ฉด 8080ํฌํŠธ๋กœ ๋„์›Œ์ง€๊ฒŒ ๋œ๋‹ค.

new > Spring Starter project

(STS๊ฐ€ ์„ค์น˜๋˜์–ด์žˆ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์—)์ด ๋ฉ”๋‰ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์—์„œ ํ–ˆ๋˜ ์ผ๋ จ์˜ ์„ค์ •๋“ค์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค. ๊ฐ„๋‹จํ•œ ๋‚ด์šฉ์ด๋‹ˆ next๋ฅผ ํ•ด์ฃผ๋‹ค ๋งˆ์ง€๋ง‰์— Dependencies ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ Web ์„ ์ฒดํฌํ•ด์ฃผ๊ณ  Finish ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋

Spring Initializr (start.spring.io)

http://start.spring.io/ ์— ๋“ค์–ด๊ฐ€๋ณด๋ฉด ๊ตฌ์ง€ ์„ค๋ช…ํ•˜์ง€ ์•Š์•„๋„ ์นœ์ ˆํ•˜๊ฒŒ Generate ํ•ด์ฃผ๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋ณด์ธ๋‹ค. ์—ฌ๊ธฐ์„œ web ์„ Dependencies์— ์ถ”๊ฐ€ํ•˜๊ณ  Generate๋ฅผ ํ•˜๋ฉด ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๊ฐ€ ์••์ถ•๋œ ์ƒํƒœ๋กœ ๋‹ค์šด์ด ๋ฐ›์•„์ง€๊ฒŒ ๋˜๊ณ  ์ด๋ฅผ IDE ์—์„œ ์—ด์–ด๋ณด๋ฉด ์œ„์—์„œ ํ–ˆ๋˜ ์ผ๋ จ์˜ ๊ณผ์ •๋“ค์ด ์„ค์ •๋˜์–ด ์žˆ๋Š”๊ฒƒ์„ ํ™•์ธํ•ด๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

๋‚ด์žฅํ†ฐ์ผ“์„ ์‚ฌ์šฉ์•ˆํ•˜๊ณ  ๋ณ„๋„ ํ†ฐ์ผ“์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

Spring boot๋Š” ์ž์ฒด์ ์œผ๋กœ ๋‚ด์žฅ WAS๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ด€๋ฆฌํฌ์ธํŠธ๋‚˜ ์ด๋Ÿฐ์ €๋Ÿฐ ์ด์œ ๋กœ ๋‚ด์žฅํ†ฐ์ผ“์„ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ํ™˜๊ฒฝ์ด๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„ค์ •์„ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋นŒ๋“œ๊ฐ€ ๋˜๋ฉด jar๋กœ ๋งŒ๋“ค์–ด ์งˆํ…๋ฐ war๋กœ ๋นŒ๋“œ ๋˜๋„๋ก ์ˆ˜์ •์„ ํ•ด์•ผํ•œ๋‹ค. (was๊ฐ€ WAR๋ฅผ ๋ฌผ๊ณ  ๋– ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ..)
<packaging>war</packaging>
  • dependency ์— tomcat์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <scope>provided</scope>
</dependency>
  • ์•„๋ž˜์ฒ˜๋Ÿผ main ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค์— SpringBootServletInitializer๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ํ•œ ํ›„ configure๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์ค€๋‹ค.
@SpringBootApplication
public class TestApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(TestApplication.class);
    }
    public static void main(String[] args) throws Exception {
        SpringApplication.run(TestApplication.class, args);
    }
}
  • ํ†ฐ์ผ“์— ๋„์šฐ๊ธฐ ์œ„ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ์„ค์ •(Project Facets)์—์„œ Dynamic Web Module์„ ์ฒดํฌํ•ด์ค€๋‹ค.

์ฐธ๊ณ  URL