원본사이트
[1] 들어가며
Spring 프레임워크의 컨트롤러와 JSP사이에서 값을 주고 받는 것은 웹프로그래밍에서 가장 기본적인 작업입니다. 하지만 값을 전달하는 방법의 종류가 많고 프레임워크특성상 많은 부분이 자동화되어 지기 때문에 그 원리를 이해하지 못한채로 사용하다 보니 세팅이 조금 다른 프로젝트를 가거나 혹은 내용이 막혔을 때 응용하기가 어려운 부분이 있습니다. 이 포스팅에서는 컨트롤러에서 JSP로 값을 전달하거나 혹은 JSP에서 입력받은 값을 컨트롤러로 전달하는 방법에 대하여 정리해보고자 합니다. 이 포스팅에서 완전 기초적인 내용부터 다루기는 어렵기 때문에 기본적으로 GET 방식과 POST방식에 대한 기본적인 이해와 Ajax, JSTL, 객체정도의 내용은 알고 있으셔야 이해하실 수 있습니다.
[2] JSP(프론트영역)에서 Controller(백엔드영역)으로 데이터 전송하기
우선은 JSP에서 Controller로 데이터를 전달하는 방법에 대해서 알아보고자 합니다. 지금 이 순간에도 수많은 웹페이지에서 게시글의 작성, 회원가입 및 로그인 등등의 작업으로 인하여 프론트단에서 백엔드단으로 데이터가 이동되고 있습니다. 프론트영역에서 백엔드 영역으로 데이터가 이동하는 경우는 GET방식과 POST방식 두가지로 이루어져 있는데 문제는 GET과 POST방식을 이용하여 Form - Action을 통해 구현하기도 하고 Ajax를 이용하거나 혹은 그냥 location href를 통해서 바로 URL주소에 태워서 보내기도 합니다. 여기에 jQuery까지 가세한다면 초심자 입장에서는 더욱더 복잡해지기 때문에 한번쯤은 이에대해서 정리할 필요가 있다고 생각합니다.
[2 - 1] Form - Action 방식을 이용한 데이터 전송
가장 기본적인 전달방식인 Form태그를 이용한 방법입니다. 아래의 코드처럼 JSP파일에서 보내고자 하는 데이터에 name속성을 지정해주고 action태그에서는 보내고자 하는 컨트롤러 url에 매핑을 해주면 됩니다. 받아주는 컨트롤러에서는 파라메타로 받아주면 되는데 이때 받아주는 파라메타의 이름은 JSP파일에서 설정한 name과 동일하게 적어주면 자동으로 파라메타 변수에 들어오게 됩니다. 처음보는 사람의 입장에서는 너무 신기한데 아무튼 spring의 힘으로 마법같은 일이 발생합니다만 여기서 놀라기에는 이른게 컨트롤러의 파라메타에 객체(DTO와 같은)를 넣어줘도 자동으로 객체에 값이 들어온다는 점입니다. 아래의 코드를 보면서 확인해 본다면 이해하실수 있을 겁니다.
JSP 영역
<form action="memberRegi.do" method="post">
이름 : <input type="text" name="userName"><br>
계정 : <input type="text" name="userId">
<input type="submit" value="전송버튼">
</form>
컨트롤러 영역
@RequestMapping(value = "memberRegi.do", method = RequestMethod.POST)
public void memberRegi(Locale locale, Model model, String userName, MemberDto dto) {
System.out.println(userName);
System.out.println(dto.getUserName());
System.out.println(dto.getUserId());
}
위의 코드에서 보시는 바와 같이 이름은 userName이라는 이름으로 전송을하고 계정은 userId라는 이름으로 컨트롤러에 전송을 하고 있습니다. 컨트롤러에서는 String userName라는 string타입의 변수와 MemberDto라는 객체로 데이터를 받고 있으며 당연히 dto에는 userName, userId라는 이름으로 변수가 선언되어 있습니다. 결과적으로 jsp에서 이름에 입력한 값은 String userName과 dto의 userName 모두에게 들어오고 계정란에 입력한 값은 dto의 userId를 통해 받을 수 있습니다. 물론 dto에는 getter와 setter함수가 선언되어 있어야 합니다.
위의 예제에서는 Form - POST방식으로 데이터를 전달했지만 GET방식으로도 얼마든지 전송이 가능합니다. JSP의 Form태그에서 method속성을 get으로 변경하고 컨트롤러에서 method부분을 method = RequestMethod.GET으로 변경만하면 됩니다. get방식으로 전송을 하면 당연히 url을 통해서 데이터가 전송되는 것은 당연합니다. 마치 아래처럼요.
'http://localhost:8080/java/memberRegi.do?userName=33&userId=44'
이것을 응용해서 아래처럼 form태그 없이 url주소로만으로 데이터 전송을 시도해볼수 있습니다.
<button onclick='location.href="memberRegi.do?userName=33&userId=44";'>url전송</button>
여기에서는 get과 post방식에 대한 차이점에 대해서 다루지는 않지만 만약 이 둘의 차이점에 대해서 잘 모르신다면 따로 공부해 보시는 것을 추천드립니다.
[2 - 2] Ajax 방식을 이용한 데이터 전송
이번에는 Ajax를 이용한 방식입니다. 여기서는 Ajax에 대하여 소개하는 페이지가 아니기 때문에 자세한 Ajax사용법에 대한 내용은 건너뛰도록 하겠습니다. Ajax는 jQuery의 Ajax를 이용하여 전송해 볼건데요 이미 Ajax를 알고 있으신 분들이라면 간단한 내용이라 바로 소스부터 보고 시작하도록 하겠습니다.
<script>
var userName = "이순신";
function ajax(){
$.ajax({
url: "memberRegi.do",
data: "userName=" + userName,
type: "POST",
success : function(data){
alert("성공")
},
error : function(){
alert("에러")
}
});
}
</script>
@ResponseBody
@RequestMapping(value = "memberRegi.do", method = RequestMethod.POST)
public void memberRegi(String userName, MemberDto dto, HttpServletRequest request) {
System.out.println(request.getParameter("userName"));
System.out.println(dto.getUserName());
System.out.println(userName);
}
위에 있는 코드만 보면 어느정도 이해가 되시리라 생각됩니다. 컨트롤러에서는 각각 String, Dto, request객체를 이용해서 데이터를 받고 있는데 어느방법으로 해도 상관없습니다. 다만 여기서 주의하실점은 @ResponseBody라는 어노테이션인데요 만약 ajax가 호출하는 컨트롤러에 @ResponseBody라는 어노테이션이 붙지 않는다면 정상적으로 동작하지 않습니다. 이에 대해서는 다음에 자세히 알아보는 시간을 가져보도록 하겠습니다.
[3] Controller(백엔드영역)에서 JSP(프론트영역)으로 데이터 전송하기
앞쪽에서 컨트롤러로 데이터를 전달하는 방법을 배웠다면 이번에는 반대로 컨트롤러에서 JSP로 데이터를 전달하는 방법에 대해서 알아보겠습니다. 여기서는 대표적으로 model객체를 이용한 방법과 ajax에 의한 호출방법 그리고 redirect시 url에주소와 함께 데이터를 전송하는 방법으로 살펴보겠습니다.
[3 - 1] Model을 이용한 데이터 전송
첫번째로 살펴볼 방식은 model객체를 이용한 방법입니다. Servlet에서는 request객체에 태워서 보냈지만 Spring에서는 model객체에 데이터를 태워서 JSP영역으로 전달합니다. 이때 model객체에는 String이나 int는 물론 Object형태의 데이터도 전달이 가능하기때문에 dto, map, list등등 어느형태의 자료도 전달이 가능합니다. 아래의 코드에서 어떻게 컨트롤러에서 model에 데이터를 태우고 jsp에서는 어떻게 전달받는지 살펴보겠습니다.
@RequestMapping(value = "index.do")
public String home(Model model) {
Map<String, String> map = new HashMap<String, String>();
MemberDto dto = new MemberDto("dtoId", "dtoName");
ArrayList<String> list = new ArrayList<String>();
map.put("userId", "mapId");
map.put("userName", "mapName");
list.add("listId");
list.add("listName");
model.addAttribute("dto", dto);
model.addAttribute("map", map);
model.addAttribute("list", list);
return "login/memberRegi.tiles";
}
리스트
${list.get(0) }
${list.get(1) }
DTO
${dto.userId }
${dto.userName }
MAP
${map.userId }
${map.userName }
[3 - 2] Redirect를 이용한 데이터 전송
이번에는 Redirect를 이용한 데이터 전송방법입니다. JSP에서 Redircet를 해도 되지만 컨트롤러에서 해도 데이터가 전송이 되는지 궁금해서 컨트롤러에서 한번 해봤는데 정상적으로 데이터가 이동하는 모습을 확인할수 있었습니다.
@RequestMapping(value = "memberRegi.do")
public String memberRegi(String userName, MemberDto dto, HttpServletRequest request) {
return "redirect:index.do?test=test";
}
@RequestMapping(value = "index.do", method = {RequestMethod.POST, RequestMethod.GET})
public String home(Model model, String test) {
System.out.println(test);
return "login/memberRegi.tiles";
}
[3 - 3] ResponseBody를 이용한 데이터 전송
이번에는 Responsebody를 이용한 데이터전송방법 입니다. mvc패턴에서는 model을 이용해서 주로 데이터를 전송하지만 요즘 많이 사용하는 리액트나 뷰에서는 responsebody를 이용한 api방식을 많이 사용하기 때문에 알아둘 필요가 있습니다. 물론 mvc패턴에서도 ajax를 이용한 통신을 할때 많이 사용 합니다.
일반적으로 Spring의 컨트롤러를 호출하면 컨트롤러에서 return하는 JSP페이지로 이동을 합니다. 그 과정에서 필요한 데이터가 있다면 model에 태워서 같이 보내는데 간혹 이런 경우가 있을 수 있습니다. 페이지 이동을 안하고 필요한 데이터만 받아야 하는 경우인데요. 이런 경우에는 컨트롤러에 @ResponseBody를 붙여 ajax를 이용해 jsp페이지와 model데이터가 아닌 필요한 데이터만을 받아오면 됩니다.
@Controller
public class TestController {
@ResponseBody
@PostMapping("/test")
public String test1() {
return "일반 String데이터";
}
}
원래 Controller에서는viewResolver가 return하는 String의 앞에는 jsp페이지의 경로를 뒤에는 .jsp를 붙여서 jsp페이지로 이동하지만 위의 코드처럼 @ResponseBody 어노테이션을 붙이면 viewResolver를 생략하고 데이터만 응답하게 됩니다. 지금은 String을 return했지만 컨트롤러의 return타입만 변경한다면 int나 dto와 같은 데이터도 당연히 전송이 가능하며 dto와 같은 데이터는 javascirpt에서 사용할 수 있도록 json형태로 보내지게 됩니다.
물론 해당 데이터를 받기 위해서는 아래처럼 ajax를 사용해야하며 그냥 주소를 브라우저에 입력하면 아무런 html태그 없이 리턴된 String데이터만 보이게 될겁니다.
function ajax(){
$.ajax({
url: "/test",
type: "POST",
success : function(data){
alert(data)
},
error : function(){
alert("에러")
}
});
}
@RestController
public class TestController {
@PostMapping("/test")
public String test1() {
return "일반 String데이터";
}
}
위의 코드는 앞서 설명한 @ResponseBody사용한 컨트롤러와 동일한 역할을 수행합니다. 이와 같이 페이지 이동이 아닌 데이터 응답만을 목적으로 하는 컨트롤러를 @RestController라고 합니다. 즉, 개발자들이 이야기하는 API가 되겠지요.
이 포스팅에서는 Spring환경에서의 데이터 받는방법 그리고 데이터를 주는방법에 대해서 알아봤습니다. 웹개발에서 데이터를 주고받는것 보다 중요하고 많이 사용되는것이 있을까요?? 제 생각에는 70% 이상의 업무가 데이터를 주고받는 선에서 끝난다고 생각합니다. 아마 이 글을 검색하고 찾아오시는 분들은 대부분 개발을 막 시작하는 분들이라고 생각합니다. 웹개발을 너무 어렵게 생각하지 않으셨으면 좋겠습니다. 그냥 화면에 있는 값을 잘 받아와 저장하고, 반대로 저장되어있는 값을 화면에 잘 뿌려주는게 웹서비스가 아닐까요?
다들 화이팅 하시길 바랍니다.
//CODE
'웹개발 > spring' 카테고리의 다른 글
스프링 AOP (0) | 2022.02.16 |
---|---|
스프링 Intercepter (0) | 2022.02.16 |
스프링 AOP 개념 이해 및 적용 방법 (0) | 2022.02.16 |
스프링 MVC 호출 순서와 기본 설정 방법 (0) | 2022.02.16 |
컨트롤 와 뷰간에 데이터 주고 받기(파라메터 종류) (0) | 2022.02.16 |
댓글