본문 바로가기
⚙️Backend/Spring

[Spring] Login 기능 및 기타 어노테이션

by Bㅐ추 2020. 6. 8.
728x90
반응형

Interceptor를 설명하기전에, Login을 구현해보도록 하겠다.

그 전에, 자주 사용되는 어노테이션들을 살펴보자.


1.  @RequestMapping

쉽게말하자면 URL을 컨트롤러에 매핑해준다.

 

1-1. 일반 매핑

  • @ReuqestMapping("/main.do")

 

: http://localhost:8787/MVC/main.do 일 때

 

1-2. 병렬 매핑

  • @ReuqestMapping(value={"/main.do ","/main2.do"})
  • @ReuqestMapping({"/main.do","/main.do"})

 

: http://localhost:8787/MVC/main.do 혹은 http://localhost:8787/MVC/main2.do 

=> 한 메서드에 여러 개의 요청 URL을 설정

 

1-3. HTTP 전송방식 지정

  • @ReuqestMapping(value="/main.do",method=RequestMethod.GET|RequestMethod.POST)

:GET방식으로 요청시 해당 메서드 호출

물론, 아래처럼 병렬 매핑이 가능하다

  • @ReuqestMapping(value="/main.do", method={RequestMethod.GET,RequestMethod.POST})

두가지 방법 혼용

  • @RequestMappling(value={"/main.do","/main2.do"}, method={RquestMethod.GET,RequestMethod.POST})

 


2.  @RequestParam & @PathVariable

Spring을 사용하다 보면 Controller 단에서 클라이언트에서 URL에 파라미터를 같이 전달하는 경우가 있다.

그리고 지금까지는 브라우저에서 매개변수를 URL파라미터에 담아 전송하면 getParameter()메서드를 이용해서 일일이 값을 얻었다.

 

바로 아래처럼 말이다.(기억난다..)

String command = request.getParameter("command");

그런데, 전송되어 온 파라미터의 개수가 많아지면 일일이 getParameter()메서드를 이용하는 방법은 불편하다. 그래서 주로 조건문을 이용해 분기하여 얻기도 하지만, 이것도 정도 껏 이지 길어지면 코드를 한 눈에 파악하기 어렵다.

 하지만, Spring에서는 이러한 단점을 보완한다.

바로 @RequestParam과 @PathVariable 을 이용해서! 

 

단, @RquestParam과 @PathVariable을 사용하는 상황은 차이가 있다.

 

Type 1 => http://127.0.0.1?index=1&page=2
Type 2 => http://127.0.0.1/index/1

 

Type 1의 경우 파라미터의 값과 이름을 함께 전달하는 방식으로 게시판 등에서 페이지 및 검색 정보를 함께 전달하는 방식을 사용할 때 많이 사용한다.
Type 2의 경우 Rest api에서 값을 호출할 때 주로 많이 사용한다.

 

2-1. @RequestParam

Type 1의 URL을 처리할 때 @RequestParam을 사용한다.


아래의 예제와 같이 사용한다.

@RequestMapping("/read")
public ModelAndView getFactoryRead(@RequestParam("no") int factroyId, SearchCriteria criteria) 
{
  //...    
}

위의 경우 /read?no=1와 같이 url이 전달될 때 no 파라미터를 받아오게 된다.
@RequestParam 어노테이션의 괄호 안의 경우 전달인자 이름(실제 값을 표시)이다.

주의해야 할 점은 파라미터의 타입이 동일해야 한다. 만약 no에 담긴 파라미터가 int형이 아니라면 오류가 발생한다.

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="parameter.do?no=123&string=abc">parameter</a>
</body>
</html>

http://localhost:8787/MVC/parameter.do?no=123&string=abc 로 요청시,

 

private static final Logger logger = LoggerFactory.getLogger(TestController.class);
	@RequestMapping("/parameter.do")
	public String testParameter(@RequestParam("no") int parameter, @RequestParam("string") String parameter2) {
		logger.info("parameter : "+parameter);
		logger.info("parameter2 : "+parameter2);
		
		return "/test/test";
	}

 

결과

*logger?

더보기

1. Log4J란?

Log4j는 Log for Java의 줄임말로 자바프로그램의 실행과적을 기록하는 도구이다.

 

2. 구성 요소

Log4j는 크게 3가지의 요소로 구성된다.

  • Logger: 로그 기록하고 Appender에 전달.
  • Appender: 로그를 파일, 콘솔, DB, 등의 위치에 출력.
  • Layout: 로그 출력 형식을 결정.

3. 로그 레벨

로그는 상태 및 목적에 따라 여러 단계(level)로 나누어진다.

  • FATAL: 어플리케이션 작동이 불가능한 상태.
  • ERROR: 요청을 처리할 수 없는 상태.
  • WARN: 처리 가능하지만, 위험성을 안고 있는 상태.
  • INFO: 정보성 메세지 확인.
  • DEBUG: 개발시 디버그를 위한 사용.
  • TRACE: DEBUG 레벨의 상세화 단계.

레벨은 FATAL > ERROR > WARN > INFO > DEBUG > TRACE의 순으로 정렬된다.
(DEBUG 레벨로 했다면 INFO~FATAL까지 모두 logging)

 

먼저 logging을 하기 위해 Logger 객체를 얻어야 하는데,

static 메서드인 LoggerFactory.getLogger() 메서드를 통해 얻을 수 있다. 

getLogger() 메서드에는 얻고자 하는 Logger명을 지정해 주어야 한다.

이때, 패키지 경로를 포함한 클래스명 또는 클래스.class를 전달하여 얻을 수 있다.


출처: https://dololak.tistory.com/631 [코끼리를 냉장고에 넣는 방법]

 출처 : https://cloudstudying.kr/lectures/346


 

2-1-1. @RequestParam의 Required 속성

 

로그인 하는 경우 ID와 비밀번호 같은 정보는 반드시 컨트롤러에 전달되어야 한다. @RquestParam의 required속성을 이용하면 반드시 전달해야 하는 필수 매개변수인 경우와 그렇지 않은 경우를 설정할 수 있다.

 

  • @RquestParam 적용시, required 속성을 생략하면 기본값은 true
  • required 를 true로 설정하면 메서드 호출 시 반드시 지정한 이름의 매개변수를 전달.(없을시 예외발생)
  • required를 false로 설정하면 메서드 호출 시 지정한 이름의 매개변수가 전달되면 값을 저장하고 없으면 null을 할당.

 @RequestParam(value="parameterName",required=true|false)

 

예제

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="required.do?string=abc">required</a>
</body>
</html>
	@RequestMapping("/required.do")
	public String testRequired(@RequestParam(value="no",required=false) Integer parameter, @RequestParam("string") String parameter2) {
		logger.info("parameter : "+parameter);
		logger.info("parameter2 : "+parameter2);
		
		return "/test/test";
	}

(int 가 아닌 Integer로 해야한다. parameter엔 null이 담기게 될 것인데, int형은 객체가 아니기 때문에 예외 발생. 그러므로 null을 담을 수 있는 Integer로 받아야 함.)

 

2-1-2. @RequestParam의 Map에 매개변수 값 설정

전송되는 매개변수의 수가 많을 경우 일일이 변수를 지정해서 사용하려면 불편하다. 이번에는 전달되는 매개변수 값들을 Map에 저장해 보겠다.

 

 @RequestParam Map<String, String> info

이름이 info인 Map에 매개변수 이름을 key로 , 매개변수의 값을 value로 저장하는 구문이다.

	<a href="paramMap.do?id=user01&password=password1">map</a>
	@RequestMapping("/paramMap.do")
	public String testMap(@RequestParam Map<String,String> info) {
		logger.info("id : " + info.get("id"));
		logger.info("password : " + info.get("password"));
		
		return "/test/test";
	}	


이렇게 @RequestParam의 경우 url 뒤에 붙는 파라미터의 값을 가져올 때 사용한다.

 

2-2. @PathVariable

Type 2의 URL을 처리할 때는 @PathVariable을 사용하게 된다.

어노테이션 이름 그대로 path를 변수처럼 사용할 수 있게 해준다.

	<a href="members/member01010/pathVariable.do">testPathVariable</a>
	@RequestMapping("/members/{memberId}/pathVariable.do")
	public String memberDetail(@PathVariable("memberId") String memberId, Model model){
		logger.info("memberId : " + memberId);
		return "/test/test";
	}

 

*정리*

어노테이션 설명 예시
@RequestParam url 뒤에 붙는 파라미터의 값을 가져올 때 사용 @RequestParam("parameterName")
 @RequestParam(value="parameterName",required=true|false)
 @RequestParam Map<Object, Object>
@PathVariable path를 변수처럼 사용 @RequestMapping("/../{pathName}")
...pathMethod(@PathVariable("pathName") Object pathName)

 


3.  Model 클래스 이용해 값 전달

Model 클래스를 이용하면 메서드 호출 시 JSP로 값을 바로 바인딩하여 전달할 수 있다.

 

	<a href="modeltest.do?test=modelTesting">modelTesting</a>
	@RequestMapping("/modeltest.do")
	public String modelTest(Model model, @RequestParam("test") String test) {
		model.addAttribute("test", test);
		return "/test/model";
	}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>${test }</h1>
</body>
</html>

 


4.  @RequestBody & @ResponseBody

@RequestBody를 사용하면 브라우저에서 전달되는 JSON 데이터를 객체로 자동으로 변환해준다.

@ResponseBody를 사용하면 지금까지는 JSP를 뷰 리졸버로 리턴한 후 결과를 표시했지만, JSP가 아닌 텍스트나 JSON으로 결과를 전송할 수 있다.

 

---*Redirect*---

기존 페이지 전환 방식은 다음과 같이 뷰페이지 경로를 뷰리졸버에게 리턴하여 결과를 표시했다.

public String 메소드이름(...){
	return "뷰페이지 경로";
}

 redirect를 사용할 때는 다음과 같이 사용한다. redirect는 뷰리졸버에게 리턴하지 않고, 해당 url를 handler mapping에게 다시 재 요청 하는 것이다. 

public String 메소드이름(...){
	return "redirect:mapping URL";
}

--------------

이제 로그인 기능을 구현해보자. 일단 pom.xml에 jackson-core-asl, jackson-mapper-asl 이 적용되어 있어야 한다.

		<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl -->
		<dependency>
		    <groupId>org.codehaus.jackson</groupId>
		    <artifactId>jackson-core-asl</artifactId>
		    <version>1.9.13</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
		<dependency>
		    <groupId>org.codehaus.jackson</groupId>
		    <artifactId>jackson-mapper-asl</artifactId>
		    <version>1.9.13</version>
		</dependency>

 

**jackson이란?(필독추천)**

더보기

출처: https://mommoo.tistory.com/83 [개발자로 홀로 서기] => 를 읽고 정리 및 복붙한 내용이니 해당 블로그 가서 읽어보는 걸 추천.

 

Spring 개발을 하다 보면, 컨트롤러 text/html 형식이 아닌 데이터 전달 목적으로 사용하고 싶을 때가 있다. 물론, 쌩 문자열인 plain/text 형식으로 보내도 상관은 없지만, 보통은 데이터 구조를 표현하는 방식인 XML 또는 JSON 형태로 많이 보낸다.(ㄱ-)

데이터의 구조를 표현하는 이유는 데이터 표현도 있지만, 사실상 데이터를 사용하는 대상이 편하게 사용하기 위해서 이다.

이때, Jackson은 JSON 데이터 구조를 처리해주는 라이브러리이다.

만약 JSON으로 데이터 구조를 표현 한다면 아래와 같다.

{    "name": "Mommoo",
     "age": 28,    "isDeveloper": true,
   "equipment": ["NoteBook", "Mouse", "SmartPhone"],
   "etc": {        "favoriteFood": 'Coffee'   }
}

자바에서 JSON데이터를 어떻게 작성할 까? 그냥 작성해야한다.(...) 아래와 같이..

나도 따라치기 싫어서 캡쳐했다..

JAVA에서는 single quotes 즉, 쌍 따옴표를 정말 문자열로 쓰고 싶을 때는 위와같이 \"문자를 붙여줘야 한다.... 가독성 무엇..?

항상 저렇게 코딩할 순 없으니~ JSON 변환용 클래스를 따로 만들고 그 클래스 안에 저장된 멤버변수를 이용하여 JSON 데이터를 출력하는 클래스들을 생각하게 된다.

 

대표적인 클래스가 Google이 만든 GSON 또는 SimpleJSON이 있다.

 

SimpleJSON을 예로 들면 윗 코딩이 아래와 같이 바뀐다.

public class Person {
    private String name;
    private String job;
    
    public Person(String name, String job) {
        this.name = name;
        this.job = job;
    }
    
    public String getName(){
        return name;
    }
    
    public String getJob() {
        return job;
    }
}
JSONObject jsonObject = new JSONObject(); // JSONObject 생성
jsonObject.put("name", person.getName()); // put
jsonObject.put("job", person.getJob()); // put
String JSON = jsonObject.toString(); // JSON객체를 String으로 변환!

아까보단 정말 낫다. 해당 방식은 지금도 많이 쓰인다고 한다.

물론 Spring에서도 위와 같이 코딩하여 리턴하더라도 충분하다. 그렇다면 Jackson은 무엇을 더 제공하길래 Spring은 Jackson을 더 선호할까?

 

< Jackson과 기존 GSON or SimpeJSON과의 차이 >

== 별 차이 없음.(응?)

 

Jackson도 여타 GSON or SimpeJSON과 같이 객체에 데이터를 셋팅해줘야 하는건 마찬가지 이다.

특별한 점은 Spring 프레임워크와 Jackson의 관계로부터 장점이 있다.

Spring 3.0 이후로부터, Jacskon과 관련된 API를 제공함으로써, Jackson라이브러리를 사용할때, 자동화 처리가 가능하게 되었다. (오~~~~~)

덕분에, JSON데이터를 직접 만들던가, GSON or SimpleJSON방식과 같이 직접 키와 벨류를 셋팅하는 방식에서 한단계 더 발전한 방식이 가능해졌다.

 

어떤 방식이길래 발전했을까?

 

< Jackson은 어떻게 동작하는가?>

Spring3.0 이후로 컨트롤러의 리턴 방식이 @RequestBody 형식이라면,

Spring은 MessageConverter API 를 통해, 컨트롤러가 리턴하는 객체를 후킹 할 수 있다.

 

>> 후킹?

운영체제가 응용 소프트웨어 등의 각종 컴퓨터 프로그램에서 소프트웨어 구성 요소간에 발생하는 함수 호출, 메세지, 이벤트 등을 중간에서 가로채서 변경하거나 보강하는데 사용되는 다양한 명령,방법,기술이나 행위.

(걍 쉽게 말하자면 중간에 가로채서 지맘대로 바꾼다는 거)

 

Jackson은 JSON데이터를 출력하기 위한 MappingJacksonHttpMessageConverter를 제공한다.

만약 우리가 스프링 MessageConverter를 위의 MappingJacksonHttpMessageConverter으로 등록한다면,

컨트롤러가 리턴하는 객체를 다시 뜯어(자바 리플렉션 사용), Jackson의 ObjectMapper API로 JSON 객체를 만들고 난 후, 출력하여 JSON데이터를 완성한다.

 

더욱 편리해진 점은, Spring 3.1 이후로 만약 클래스패스에 Jackson 라이브러리가 존재한다면,( 쉽게 말해Jackson을 설치했느냐 안했느냐 ) 자동적으로 MessageConverter가 등록된다는 점.

덕분에 우리는 아래와 같이 매우 편리하게 사용할 수 있다.

 

@RequestMapping("/json")
@ResponseBody()
public Object printJSON() {
    Person person = new Person("Mommoo", "Developer");
    return person;
}

이제는 그냥 데이터 인스턴스만 리턴 하더라도 JSON 데이터가 출력된다.

< 그 전에 알아야 할 지식 >

Jackson은 기본적으로 프로퍼티로 동작한다.

Java는 프로퍼티를 제공하는 문법이 없다. ( 멤버변수랑은 다르다. )

Java의 프로퍼티는 보통 Getter 와 Setter의 이름 명명 규칙으로 정해진다.

문법적으로 정해지는것이 아니다 보니, 개발자가 일일이 신경써줘야 하는게 자바의 단점 중 하나.

Person 같은 경우는 Getter만 존재 하므로, Getter를 기준으로 프로퍼티를 도출 할 수 있다.

NameJob이 Person 프로퍼티이다.

Person의 멤버변수 이름도 똑같이 name, job이지만,

앞서 설명했듯이, 프로퍼티Getter, Setter기준이므로 멤버변수 이름을 변경하더라도 상관 없다.

갑자기 프로퍼티를 설명한 이유는 많은 라이브러리가 해당 프로퍼티 개념으로 작동하기 때문이다.

Jackson라이브러리도 마찬가지 이다. JSON데이터로 출력되기 위해서는 멤버변수의 유무가 아닌 프로퍼티 즉, Getter, Setter를 기준으로 작동한다.

예로 아래와 같이 코딩하더라도 전혀 문제가 없다.

public class Person {
    public String getName() {
        return "Mommoo";
    }
    
    public String getJob() {
        return "Developer";
    }
}
​
@RequestMapping("/json")
@ResponseBody()
public Object printJSON() {
    return new Person();
}

결론적으로 Jackson을 사용한다면, Getter에 신경쓰셔야 한다.

Jackson의 데이터 매핑을 Getter가 아닌 멤버변수로 할 수 있는 방법은 있을까?
Jackson은 이와 관련하여 @JsonProperty 어노테이션 API를 제공한다. 아래와 같이 멤버변수 위에 프로퍼티 이름과 함께 선언해준다면, JSON데이터로 출력 된다.

 

public class Person {
    @JsonProperty("name")
    private String myName = "Mommoo";
}

위의 예시는 {"name": "Mommoo"}로 출력.

그렇다면 JSON 매핑을 멤버변수로 하고 싶다면, 매번 @JsonProperty를 선언 해야 할까? 귀찮다...

애초에 Jackson 매핑 구조를 바꾸면 어떨까 하는 생각이 든다.

 

Jackson은 매핑 법칙을 바꿀 수 있는 @JsonAutoDetect API를 제공한다.

위 예시와 같이 멤버변수로만 Jackson을 구성하고 싶은 경우 @JsonProperty를 일일이 붙이는 것보다 아래와 같이 설정하는 것이 더 편리하다.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Person {
    private String myName = "Mommoo";
}

@JsonAutoDetect는 멤버변수 뿐만 아니라, GetterSetter의 데이터 매핑 정책도 정할 수 있다. 만약 아래의 경우는 멤버변수 뿐만 아니라, 기본정책인 Getter역시 데이터 매핑이 진행된다.

이하 생략.


 

 

mvclogin.jsp 에 해당 html태그를 추가한다.

	<table>
		<tr>
			<th>ID</th>
			<td><input type="text" id="memberid"></td>
		</tr>
		<tr>
			<th>PW</th>
			<td><input type="password" id="memberpw" ></td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="button" value="login" onclick="login();">
			</td>
		</tr>
		<tr>
			<td colspan="2" align="center" id="loginChk"></td>
		</tr>


	</table>

 

그리고, 해당 javascript를 구현한다.

 

	<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
	<script type="text/javascript">
	
		$(function(){
			$("#loginChk").hide();

		});
		
		function login(){
			// (1)
			var memberid = $("#memberid").val().trim();
			var memberpw = $("#memberpw").val().trim();
			
			console.log(memberid+"/"+memberpw);
			
			// (2)
			var loginVal={
					"memberid":memberid,
					"memberpw":memberpw	
			};
			
			// (3)
			if(memberid == null || memberid=="" || memberpw == null || memberpw==""){
				alert("ID 및 PW를 확인하세요.");
			}else{
				// (4)
				$.ajax({
					type:"post",
					url:"ajaxlogin.do",
					data:JSON.stringify(loginVal), //(5)
					contentType:"application/json",
					dataType:"json",
					success:function(msg){ 
						alert(msg.check);
						if(msg.check==true){ // (6)
							location.href="list.do";
						}else{
							$("#loginChk").show().html("ID or PW 잘못"); // (7)
						}
					},
					error:function(){
						alert("통신실패"); // (8)
					}
					
				});
			}
		
		};
		
		
	</script>

 

AJAX 동작방식을 알고있다는 가정하에 설명하겠다.

 

( 1 ) :로그인 버튼이 클릭이 되면 해당 memberid와 memberpw를 저장한다.

( 2 ) : 후에 JSON 문자열{"key":"value",...} 로 변환해주기 위해 javascript객체에 저장한다.

( 3 ) : 데이터 유효성 검사

( 4 ) : 데이터가 모두 정상적으로 들어있을 때 , 비동기 통신 시작.

( 5 ) : JSON.stringify() 메서드로 자바스크립트 객체를 json객체로 변환 후 ajaxlogin.do로 전송.

( 6 ) : 로그인 성공

( 7 ) : 로그인 실패

( 8 ) : ajax통신 실패

 

MemberController.java 에 다음을 추가한다.

@RequestMapping(value="/ajaxlogin.do", method=RequestMethod.POST)
	@ResponseBody
	public Map<String,Boolean> ajaxLogin(HttpSession session, @RequestBody MemberDto dto){
		// ( 1 )
		logger.info("LOGIN");
		
		MemberDto res = biz.login(dto); // ( 2 )
		
		boolean check = false;
		
		if(res!=null) { // ( 3 )
			session.setAttribute("login", res);
			check = true;
		}
		
		Map<String ,Boolean> map = new HashMap<String,Boolean>();
		map.put("check", check);
		
		return map;
	}

( 1 ) : session에 로그인 정보를 담아주어야 하므로 HttpSession session 을 매개변수로 받아야 한다.

( 2 ) : JSON으로 전송된 데이터 loginVal 을 MemberDto속성에 자동으로 설정해준다.(@RequestBody)

( 3 ) : 로그인 성공

( 4 ) : @ReponseBody 태그로 인해 map이 JSON으로 변환되어 ajax통신이 이루어진다.

 

 


dto안에는 어떤 데이터가 들어가야 할까? 입력한 아이디(memberid) 와 비밀번호(memberpw)가 들어있어야 할 것이다.

이 데이터는 어디에서 입력하는가? mvclogin.jsp의 form에서 입력한다. 거기에서 입력한 데이터가 이 controller로 넘어와야 한다.

 

전에는 해당 데이터를 parameter로 해서 POST방식으로 하나하나 받아서 로그인 기능을 구현 해왔지만, AJAX를 이용해서 로그인 기능을 구현할 수 있다.

 

지금은 사용자에게 입력받은 데이터를 var변수에 각각 받아 최종적으로 javascript 객체에 저장하고 있다. 왜 하필 자바스크립트 객체일까? 해당 데이터를 비동기통신을 통해 controller와 소통(쉽게 말해서 통신)을 해야 하는데 비동기통신의 데이터 형식은 xml아니면 json으로 주로 사용한다. JSON.stringify()메서드를 이용해 자바스크립트를 JSON으로 변경할 수 있으므로 자바스크립트 객체로 선언해주는 것이다. 

그리고 (JSON으로 ) 변환된 데이터는 해당 Controller(ajaxlogin.do)로 오게 되는데 이때 @RequestBody가 해당 JSON객체를 자동으로 Java Object로 변환하고 그 내부의 데이터를 알아서 memberDto에 담아주게 된다.

이러한 일을 jackson이 할 수 있도록 도와준다.

 

결국 다시 controller는 결과값으로 json객체를 리턴해야한다.(ajax에 json을 받겠다고 명시되어 있어서.) 이걸 @ResponseBody가 해당 리턴 값을 자동으로 JSON으로 변환한다. 물론 이것도 jackson이 도와준다. 내부적으로바껴지는과정은 신경 안써도 된다. 알/아/서 변경이 된다.

 

즉 , 쉽게 설명하자면
@RequestBody:Request로 들어오는 parameter 인 JSON들을 자바오브젝트로 바꿔줌.
@responseBody:Response시에 자바오브젝트를 JSON으로 변환해서 보내줌.
=> 이러한 변환을 Jackson이 도와준다는 것이다.

 

 

 

--출처--

https://mommoo.tistory.com/83

https://hongku.tistory.com/124

https://sjh836.tistory.com/143

https://mangkyu.tistory.com/72

https://gs.saro.me/dev?tn=556

https://elfinlas.github.io/2018/02/18/spring-parameter/

https://mrrootable.tistory.com/75

728x90
반응형