반응형

 

https://extsdd.tistory.com/101

 

[Spring/eGov ] #5 웹 서비스 만들기 1 / 컨트롤러 생성 / VO 생성 / Controller / 다른 URL 페이지 포워딩 하�

https://extsdd.tistory.com/100 [Spring/eGov] #4 스프링 Sample 기본 예제 프로젝트, 패키지 이름 바꾸기 / 파일 찾기 extsdd.tistory.com 저번 시간에 드디어 예제 프로젝트의 정체성을 완전히 내걸로 만들어놨..

extsdd.tistory.com

 

 

  저번시간에 사용자가 URL요청을 하면, 서버가 다른 페이지로 넘겨주는 기능을 구현했다. 그런데 만약 여러 주소중 알맞은 주소로 포워딩 시켜준다고 하면 reqUrlNaver.do , reqUrlDaue.do, reqUrlGoogle.do 이런식으로 모든 .do 요청을 다 만들어야 할까?.! 아니다.

 

  페이지를 포워딩 시켜주는 reqUrl.do는 그대로 유지하고, 서버가 판단해주고 알맞은 서버로 포워딩 해주면 될 것같다. 그럴려면 사용자가 reqUrl.do를 호출할때 어떤 주소로 포워딩할 정보를 담아줄지 정보를 같이 넘겨줘야하는데, 이번시간에는 그 정보를 어떻게 넘겨주는지 알아보자! 많이 할껀 없고 저번에 VO를 만들어놨기때문에 좀 수월할 것이다.

 

@ModelAttribute

 

  자 사용자 화면에서 우리 서버로 요청을보낼때 데이터를 실어보내는 방법에는 여러가지가 있다.

  1. URL param (PathVariable)

  2. HttpServletRequest param

  3. RequestParam

  4. 기타 등등..

  꽤 여러가지가 있는데 우린 RequestParam 방식과 비슷하지만, 자동적으로 우리 VO와 매핑시켜주는 @ModelAttribute 방식을 이용해서 구현 할 예정이다.

 

  먼저 RequestParam방식은 @RequestParam("variable1") String variable1 이런식으로 사용자가 variable1로 데이터를 실어서 주면 스프링에선 String 자료형으로 variable1의 변수로 이용할 수 있다인데, 이게 불편한점이 머냐면, 가끔 변수 한, 두개 저렇게 해주면 쓸만한데 예를들어 사용자 페이지에서 변수 데이터 100개를 가져 와야한다고 치면

 

  @RequestParam("variable1") String variable1

  @RequestParam("variable2") String variable2

  @RequestParam("variable3") String variable3

  ...

  @RequestParam("variable100") String variable100

 

  이걸 다달아줘야한다.. 그렇지 않으려면 방법이 멀까!? 바로 VO를 이용하면 된다. 저번시간에 VO라는 친구들 배워봤다. 다시 리마인드 해보자면

 

 

  이런식이다. VariableVO에 변수 1부터 100까지 다 선언해놓고 그 100가지 변수를 담고있는 데이터 주머니를 VariableVO라고 부르는 것이다. 그건 알겠고 이제 그 VO랑 어떻게 하겠다는 건데?

 

 

  히힣.. 놀랍게도 벌써 그 구분은 저번에 코드에 넣어놨다. 저 1번 박스에 있는 부분만 한번 보자. 가장 핵심은 @ModelAttribute 어노테이션인데이 어노테이션은 사용자 페이지에서 넘어온 정보들을 서버에서 있는 스프링 프로젝트(java)단에서 쓸 수 있게 해주는 역할을 한다.

 

  자 그럼 저 어노테이션이 뭔 역할을 하는지 이제 알았고 searchVO라는것은 멀까 search..! 말그대로 찾는다..! 뭐를? VO를..!! VO를 찾는다..! 라는 뜻이다. 이걸 박아놓으면 사용자 요청에 어떤 데이터들이 들어올텐데 이걸 우리가 담을 데이터 바구니(VO)에 알아서 맵핑을 해주겠다는 것이고, searchVO로 불러온 데이터들은 보통 주로 쓰이는 메인 VO이기 때문에 자동으로 .do인 자바 요청이 끝난뒤 다시 사용자 페이지에 결과를 줄때 자동으로 모델에 추가해주는 기능을 한다. model.addAttribute("searchVO"); 이 한줄을 안써도 자동으로 된다는 뜻이다.!

 

  자 이제 개념은 알겠고, 혹여나 몰라도 상관없다. 이제 실습을 통해서 데이터를 어떻게 가지고 오는지 확인해 보자!

 

 

  자 저번에 우리가 만든 VO를 보면 reqParam 이라는 변수를 만들어 놨다. 이제 우리가 페이지 요청을 할때 저 데이터에 담아서 보내볼 껀데, 그 과정을 확인하려면, Debug를 해야한다!

 

Debug (디버그)

 

  오.. 오랫만에 그럴듯한 단어가 나왔다. 시스템에 문제가 생겼을때 개발자들이 말하곤한다. "디버깅해봐!", "디버깅 태워봐!!" 이런식으로 Debug + ing = Debugging 표현하는 것을 어꺠너머로 들어본 사람도 있을 것이다.

 

  TMI이긴 하지만, 근본적인거를 간단히라도 알고 하는게 좋으니까 한번 알아보자 ^_^. 자 Bug는 멀까!? 이거 게임많이 해본 사람이라면 아주 많이 들어봤을것이다. "아ㅡㅡ 버그 생겼어", "이거 버그 아냐!?" 뭔가 시스템적으로 오류가 생기면 버그가 발생했다고들 한다. 버그의 어원은 1940년대 하버드에서 컴퓨터 실험을하다 오작동이 발생해 확인해보니 컴퓨터 하드웨어에 모기가 껴있어서 발생해서 "Bug"라고 불리게 되었다.

 

  자 버그=오작동! 정도로 해석하면 되니 debug는 더 쉬울 것이다. de-라는 접두사는 반대의미를 가지고 있다. debug니 버그가 발생하지 않도록한다는 의미라고 해석하면된다.

 

  그럼 debug의미는 알겠는데 구체적으로 우리 프로그래머 단에서 하는건 먼데? 라고한다면, 코드를 한줄씩 돌려보고, 그 순간에 컴퓨터가 처리하고 있는 객체의 정보를 들여다 볼 수 있다. 즉, 우리가 어떤 요청을 했을때 우리가 보는 화면엔 "페이지를 표시할 수 없습니다" 이런 화면만 뜨면, 문제가 발생한 것은 알 수 있지만, 이 복잡한 컴퓨터 시스템에서 구체적으로 어떤 부분떄문에 문제가 발생했는지는 힘들 것이다. 실행->결과 이렇게만 나오니까.

 

  하지만 Debug과정을통해서 실행->과정->결과의 단계로 우리가 과정을 들여다보면서 원하는 코드구문에 BreakPoint를 걸어 한줄한줄 코드를 들여다보면서 어디서 어떤 부분에 어떤 데이터때문에 문제가 발생하는지 찾아볼 수 있는 분석 툴이라고 보면 된다!

Debug 모드로 프로젝트 실행

 

 

 

  자 우리가 원래 서버를 실행시킬때 보통 재생버튼을 눌러 실행해 보았으나, 이번에는 서버탭(1)을 클릭하고 원하는 서버를 클릭한뒤(2) 벌레모양의 버튼(3)을 눌러보자! 이쯤되면 이제 저 버튼이 왜 벌레오먕인지도 알 것이다. 저 버튼은 Debug 버튼인거다! 벌레잡는 버튼! = 버그 잡는 버튼!!

 

  http://localhost:8080/

 

  자 디버그 모드로 실행되면 뭐..그냥 Run(재생버튼) 했을때와 크게 다른점은 바로 안느껴진다. 일단 서버가 실행되면 정상적으로 실행됐는지 확인해보기 위해서 위 주소로 접속해서 페이지를 정상적으로 띄어주는지 확인해주자. 문제가 없다면 우리가 전에 만들었던 주소도 호출해보자!

 

  http://localhost:8080/reqUrl.do

 

  자 저번에 우리가 네이버로 넘어가는 코드를 작성했으니 네이버로 넘어갈 것이다. 자 이제 전에 만들었던 소스들이 문제가 없다는걸 확인했으니 본격적으로 진행해보자.

Perspective Java EE로 변경

 

  디버그모드를 원할히 이용하려면 Perspective를 변경해줘야한다. 한국말로 관점 정도로 해석하면 되는데,

 

 

  우측 상단 1시방향 구석을 보면 저기에 Perspective를 설정 할 수 있다. 지금 현재 우리는 저 빨간박스 우측에 G머시기가 써져있는 아이콘인 EgovFrame 관점으로 되어있을텐데, 이 Perspective로 하면 브레이크 포인트를 걸 수가 없다. 그러니 우리는 저 자바 콩 아이콘이 그려져있는 저 빨간박스에 있는 버튼을 눌러 Perspective를 변경해주자.

Breakpoints 탭 추가 "Alt + Shift + Q" + "B"

 

  자 디버그 모드로 들어왔는데 머 딱히 달라진게 없어서 별거 없다고 생각한 사람도 있겠지만, 이제부터 시작이다. 일단 Breakpoints 라는 것이 있는데 한국말로 "중단점"이다. 풀어말하자면 멈출 부분이란 뜻이다. 이 서버가 돌아가기 위해선 우리가 작성한 소스코드 일부분을 포함해서 수천, 수만 줄의 소스코드들이 있는데, 이중 우리가 멈춰서 보고싶은 부분에 중단점을 걸어 프로그램을 잠시 그 순간에 잡아두도록 설정할 수 있는 부분이다.

 

  일단 "ALT + SHIFT + Q" 버튼을 눌러보자, 3개의 키를 동시에 눌러주면 된다. 그리고 1초..?2초..?정도 기다려주자. 바로는 안뜨더라..ㅋㅋ

 

 

 

  그럼 화면 우측 하단 구석에 저런 화면이 뜰텐데 우린 Breakpoint를 열어줄꺼니 "B"버튼을 한번 더 눌러주자! 그럼 2번 화면처럼 Breakpoints 탭이 생긴 것을 볼 수 있다. 이 창이 바로 BreakPoints 를 관리하는 화면이다. 사실 단축키 말고 마우스로도 설정에 들어가 이탭을 불러 올 수는 있는데, 너무 과정이 많아서 그냥 단축키를 외우도록하자! "Alt + Shift + Q" + "B"!!

 

Breakpoints 선언 (Ctrl+Shift+B)

 

  자 이제 본격적으로 프로그램을 멈춰줄 중단점을 선언할건데 우린 요청한 데이터가 서버로 들어와 VO에 자동으로 Mapping 되는지를 확인할 것이기 때문에 우리가 만든 요청부분에 Breakpoints를 만들어주자.

 

 

  자 우리가 만든파일 16번 줄에 있는 return "redirect:http://www.naver.com";줄에 마우스를 눌러 입력커서를 저 위치로 이동시키고 Ctrl+Shift+B 단축키를 눌러보자! (1번 박스) 그럼 2번 박스위치에 파란색 점이 하나 찍힐 것이고 3번 박스인 Breakpoints 박스에 해당 중단점이 하나 추가될 것이다! (Brekapoints 박스가 하단에 있을테지만 난 우측이 편해서 우측으로 옮겼당 ㅎㅎ)

 

  1번 위치에서 Ctrl+Shift+B버튼을 눌렀을때 중단점이 추가되지 않은 사람들은 아직 Perspective가 egovFrame일 확률이 높다. 본문 위를 살펴보면 Perspective를 Java EE로 바꾸는 과정이 있는데 따라해주면 해결된다.

 

테스트 요청

 

  localhost:8080/reqUrl.do?reqParam=999

 

  자 이제 저 주소를 한번 들어가보자. 달라진 점이라면 기존 localhost:8080/reqUrl.do 뒤에 ?가 붙었다. ?가 붙으면 뒤쪽은 서버로 전달할 Data를 보내겠다는 의미정도로 해석하면 되겠다. ?뒤쪽을 보면 우리가 VO에서 선언한 변수명인 reqParam이 있다. reqParam=999 의 의미는 저 변수에 999라는 변수를 담아서 보내겠다는 뜻이다 엔터를 쳐보자!

 

 

 

  자 이클립스로 돌아와보면 이런 화면이 떠있을텐데, 중단점을 인식했고, 디버그가 걸렸으니, Perspective를 debug관점으로 바꿀꺼냐는 것인데, 뭐 우린 Debug 관점의 고급기능을 이용할 일은 없으니 1번을 체크해주고 2번을 눌러 관점을 바꾸지 않겠다고 하고 진행한다.

 

 

  소스 코드를 보면 우리가 중단점을 건 부분이 초록색으로 표시되며 현재 저부분에서 프로그램이 멈춰있다! 라고 생각하면 된다. 그럼 저 당시의 변수들을 어떻게 보는지 알아보장!

 

 

  자 1번 위치에 마우스를 올려 한 1초정도를 기다리면 노란색 박스가 뜨는데 거기 보면 지금 FwdVO형태로 이름이 맞는것끼리 자동으로 매핑된 reqParam이 들어온 것을 볼 수 있다. 값도 보면 999로 들어온 것을 볼 수 있다.

 

  현재 우리 VO에는 reqParam으로 한개 변수 밖에 없지만, 만약 여러개의 변수를 전달한다고 하면

 

  http://localhost:8080/reqUrl.do?reqParam=999&reqName=꺄하하

 

  이런식으로 변수뒤에 "&" 기호를 붙혀 추가로 전달이 가능하다. 아마 저 주소를 그대로 입력하면 오류가 나지는 않는다. 매핑할 수 있는것만 매핑하는 것이기 때문에 FwdVO에 선언되지 않은 reqName이란 변수는 매핑되지 않고 그냥 무시 되는 것이다!

 

  그리고 http://localhost:8080/reqUrl.do?reqParam=꺄하하

이 주소를 호출하면 역시 에러가 발생할 것이다 왜냐하면 FwdVO에 reqParam이 정수형인 Int로 선언되어 있는데 데이터로 "꺄하하"라는 String 형의 변수가 들어오니 형이 맞지않아 매핑에 실패하는 것이당 ㅎㅎ

 

 

  마지막으로 이런 URL 파라미터 전달방식으로 100개의 변수를 전달한다고 하면, 주소가 엄청나게 길어질 것이다. 이렇게 하지 않기위해 나중에는 form에 있는 정보를 그대로 보내는 방식이 있는데 그건 나중에 배워보도록하고 일단은 한두개 전달하는건 이방식이 좋으니 이렇게 진행해보자.

 

 

  자 다시 이상황으로 돌아와서 보면, 지금 저 16번째줄에 프로그램이 걸려있고 저 페이지를 요청한 인터넷 창을보면 아직도 모래시계가 뜨면서 멈춰 있는 것을 볼 수 있다. 이떄 한줄 씩 진행하고 싶을때는 F8을 진행시켜 진행해보자.

 

  - F5 : 함수 안으로 들어가본다

  - F6 : 코드를 한줄씩 실행시킨다

  - F7 : 이 함수를 나온다.

  - F8 : 걍 진행한다.

 

  이렇게 4가지 단축키로 프로그램 실행을 분석할 수 있다. 보통 F5는 잘 안누른다. 해당 함수안까지 봐야하는 세부분석이 필요할 때 보통 누르고, 보통은 F6을 눌러 한줄씩 실행한다. F7도 보통 많이 쓰진 않았다. F8은 중단점을 풀어 진행한다. 하지만 계쏙 진행하다 내가 만들어놨던 중단점을 또 만나면 그때 다시 중단점이 걸린다.

 

  자 저상태에서 F8을 눌렀다면 중단점에서 빠져나와 프로그램이 계속 실행되고 최초 해당 URL을 요청했던 인터넷 페이지는 정상적으로 Naver를 띄우고 있을 것이다.

 

사용자 요청에 따른 분기처리

 

  자 그럼 우리가 사용자가 reqParam에 1을 담아서 주면 네이버로 연결시켜주고, 2를 담아서 주면 다음에 연결시켜주는 소스를 작성해보자.

 

 

  자 기존 return 머시기 한줄 있던 코드대신 저 빨간 박스에 있는 코드들로 변경해주자. 그리고 Breakpoint도 ㄷ저 if문 처음 시작할때로 지정해주자.

package cpservice.fwd.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import cpservice.fwd.service.FwdVO;

@Controller
public class FwdController {

	@RequestMapping(value = "/reqUrl.do")
	public String selectReqUrl(@ModelAttribute("searchVO") FwdVO searchVO, ModelMap model) throws Exception {
		
		if (searchVO.getReqParam() == 1){
			return "redirect:http://www.naver.com";
		}else if(searchVO.getReqParam() ==2){
			return "redirect:http://www.daum.net";
		}
		
		return "redirect:http://www.google.com";
		
	}
	
}

 

귀찮은 사람을 위해서 코드도 첨부했당. ㅎㅎ

 

 

  코드 분석을 해보자.

 

  16번 줄을 보면 searchVO에서 reqParam의 값이 1이면

  17번 줄처럼 네이버로 연결시켜준다.

  18번 줄처럼 만약 reqParam의 값이 2면

  19번 줄처럼 다음으로 연결시켜준다.

 

  만약 reqParam의 값이 1도 2도 아니고 없거나 다른 숫자가 들어오면 그냥 구글로 넘겨준다!

 

  이정도 코드로 보면된다. 여기서 물어볼만한건, searchVO에서 값을 쓰고, 꺼내오는건 저번 시간에 VO를 선언할때 안에 같이 따라오는 get, set 함수를 지정했기 떄문에 이걸로 꺼내오느라고 searchVO.getReqParam() 함수를 사용하는 것이고 22번줄에 구글로 포워딩시켜주는 return을 넣어놓은 이유는 사용자가 요청을 줄때 꼭 reqParam을 안넘겨 줄 수도 있고, 혹은 넘겨준다 하더라고 1이나 2가 아닌 999를 넘겨줄 때는 처리할 로직이 없기때문에 그 아무것도 아닌경우는 구글롤 넘겨주겠다~ 해주는 로직이다.

 

  자 16번 if문줄에 브레이크 포인트를 걸었다면 진짜 값들을 보면서 어떻게 처리되는지 확인해보자. 코드가 수정됐으니 다시 Debug버튼을 눌러 서버를 재부팅 시켜주고 주소를 요청해보자!

 

http://localhost:8080/reqUrl.do

 

  자 우리가 처음 작성했던 기본 구문이다 어떻게 되는지 보기위해 인터넷창에 한번 쳐보자!

Variables 탭 추가 "Alt + Shift + Q" + "V"

 

  일단 우리가 들어온 값들을 계속 마우스 올려 보면 귀찮으니 이걸 보여주는 탭을 추가해보자, BreakPoints창을 연것과 단축키가 비슷하다, 알트+쉬프트+Q를 누르면 한 1~2초뒤 우측 하단에 머 창이뜨는데 거기서 V를 눌러주자.

 

 

  그럼 이렇게 현재 값들을 볼 수 이쓴ㄴ Variables 탭이 추가된다. 이제 코드를 한줄한줄 돌리면서 값들이 바뀌면 실시간으로 저 Variable들이 변화를 하게 된다. 위 사진처럼 searchVO를 펼쳐보면 reqParam이 보이게되고, 변수를 담아서 보내지 않으면 0을 보내주는 것을 알 수 있다.

 

 

  자 다시 돌아와서 현재 16번 줄에 멈춰있고 지금 이순간 searchVO에 reqParam은 0의 값이 들어온 것을 볼 수 있다. 이제 F6을 눌러 한줄 진행하면 16번 줄의 if문을 실행한 결과로 넘어간다. F6을 한번 눌러보자.

 

 

  자 1번 위치에서 2번 위치로 이동했다. 이유가 멀까. 간단하다 reqParam의 값이 0이니까 저 if문에 reqParam이 1이 아니기때문에 통과한 것이다. 한번더 F6을 눌러보자.

 

 

  자 2번 박스의 if문에도 해당하지 않으니 당연히 3번 박스로 커서가 이동할꺼고 이때 F8을 눌러 진행을 시키면 페이지가 google로 이동한 것을 볼 수 있다.

 

 

  이제 URL에 값을 넣어서 한번 테스트해보자.

 

  http://localhost:8080/reqUrl.do?reqParam=1

 

  다시 디버그가 걸릴텐대 한번 확인해보장

 

 

 

  자 우측 Variable화면을 보면 reqParam이 1로 들어온 것을 볼 수 있고 일단 16번줄에 브포를 걸었으니 멈춰있는데 F6을 한번 눌러보자!

 

 

  자 reqParam에 1이 들어왔으니 당연히 if문 내부로 통과할 것이고 커서가 2번 박스로 들어올꺼다. 여기서 F8을 눌러 진행하면 naver로 포워딩이 되고, 다시 reqParam을 2로 요청하고 다시 디버그 결과를 보면 daum으로 포워딩 되는 것을 볼 수 있다!

 

요청에 따른 분기처리는 여기까지~

 

 

#스프링 #Spring #전자정부프레임워크 #웹서비스 #만들기 #URL파라미터 #디버깅 #Debug #방법

 

 

반응형
  1. 김진호 2021.11.23 16:59

    정말 친절하게도 아주 자세하게 설명해 주셨네요.
    수고 많으셨습니다.
    감사합니다 ^^

+ Recent posts