공부할수록 왜 스프링 스프링 하는지 마음은 알 것 같은데 아직 머리가 따라오지를 못하네요;; DispatcherServlet 배우기 전까지가 따아아아악 좋았습니다 흠흠.. 매 포스팅 전에 직전 포스팅 열심히 정독하고 오는데도 다 쓰고 나면 개념이 뒤엉켜서 괴롭지만 밥벌어 먹고 살려면 열심히 살아야죠 아니 근데 Postman는 왜 안되는거죠? Sign up까지 했는데 말이죠.. 밀린 할 일은 많고 Postman는 안되서 답답해 미치겠어서 제가 내린 결론은 여유가 생겼을 때 Postman 사용법을 제대로 알아보고 오겠습니다. 네 지금은 안하겠다는 말입니다. 이번주도 모두 좋은 한 주 되시길 바라고 급 더워졌다가 또 기온이 내려갈 예정이오니 얇은 옷 여러 개를 걸쳐 입으셔서 현명하고 건강한 스타일링 하시기 바랍니다.💚
- 컨트롤러 컴포넌트
- @RequestMapping 과 @PathVariable
- 컨트롤러의 개념을 이해하고 컨트롤러를 작성한다.
- 웹 요청방식에 대해 대응하는 코드를 작성하고, HTTP URL 경로를 통한 변수를 처리할 수 있다.
1) 웹 어플리케이션 최전방에서 사용자 요청을 접수
2) URL을 기준으로 요청을 처리할 Controller를 찾음
3) 해당 Controller를 호출 및 실행
Front Controller가 적적할 Controller를 찾을 때는 URL를 기준으로 찾습니다.
- 1) 사용자 요청(URL 기반)에 해당하는 Controller의 특정 메소드가 호출됨
- 2) Controller는 요청의 파라미터가 있으면 처리하고
- 3) 비즈니스 처리를 위해서 서비스 컨포넌트를 주입 받아서 실행
- 4) 실행된 결과를 전달받아(화면에 대한 정보와 함께) DispatcherServlet에게 반환
🎯 사용되는 Annotation
※ @Controller
※ @RequestMapping
※ @Autowired
추가설명
1) URL을 기반으로 Controller의 특정 메소드가 호출되기 때문에 개발자는 URL에 맞는 특정 메소드를 개발하면 됩니다.
2) URL에 파라미터가 있을 수도, 없을 수도 있습니다. 그렇기 때문에 URL에 파라미터가 있는 경우엔 그 파라미터를 처리하면 됩니다.
3) 비즈니스 처리는 모델에서 하는 부분입니다. Controller의 소관은 아니죠. 하지만 Controller가 적절한 모델(= 서비스)을 호출하는데 이를 위해 서비스 컨포넌트를 주입(DI) 받아서 실행하는 구조라는 뜻입니다.
@Controller : 클래스 레벨에 붙여주는 어노테이션입니다. 특정 클래스에 붙여주면 ' 이 클래스는 컨트롤러다' 라는 뜻입니다.
@RequestMapping : 메소드 레벨에서 붙여주는 어노테이션입니다. 이 어노테이션이 붙은 메소들 중에서, 들어오는 사용자 요청과 일치하는 메소드가 실행됩니다.
@Autowird : 서비스 객체에 붙여주는 어노테이션입니다. 그래야 Controller에서 서비스 객체를 주입 받아서 참조할 수 있고, 참조한 서비스 객체를 통해서 DAO를 사용할 수 있기 때문입니다. Controller에서 직접 DAO를 사용할 수는 없습니다. Controller -> Service -> DAO 이렇게 접근합니다.
🧸 Class Level Mapping vs Mehtod Level Mapping
📗 요청 방식 선택
※ GET, POST, PUT, DELETE ...@Controller @RequestMapping("/bbs") //클래스 레벨 매핑 public class BbsController{ @RequestMapping("/list") //메소드 레벨 매핑 public String list(){ return "bbs/list"; } @RequestMapping(value="/write", method=RequestMethod.POST) public String doWrite(){ return "bbs/write_ok"; } }
- 참고) Spring 4.3 이후
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping 추가
URL를 처리하는 메소드에 @RequestMapping 어노테이션을 붙여줍니다.
위 코드는 URL을 처리하는 Controller의 메소드를 몇 개 예시로 작성했습니다.
먼저, 메소드 레벨 매핑을 먼저 보면 URL이 "~/list"로 오면 list() 메소드가 실행되면서 적절한 페이지 경로를 리턴합니다.
클래스 레벨 매핑을 본다면, URL이 "~/bbs/write"로 오면 일단 저 클래스를 무조건 탑니다. "/bbs"가 URL에 써있기 때문이죠.
그리고 하위 "/write"를 처리할 메소드를 찾아 호출합니다.
이렇게 구조적으로 @RequestMapping을 작성하면 더 좋습니다.
요청 방식은 일반적으로 GET, POST 방식을 많이 사용합니다. RESTful 방식이면 PUT, DELETE 방식도 추가되어 사용됩니다. URL+요청 방식 두 가지를 모두 보고 딱 맞아떨어지는 메소드가 호출하게 됩니다.
참고로, Spring 4.3 이후, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping가 추가됐습니다. 따라서 @RequestMapping 어노테이션 쓰고 method 값에 요청 방식 기입할 필요 없이, 요청방식마다 전용 어노테이션이 생긴 셈이죠... 정말 대단... 존경쓰.. 어떻게 이런 생각을 했을까요?ㅜ
- 요청 URL을 파라미터로 사용(경로변수)
※ 예) http://cafe.daum.net/sq99/2hq/68443
※ 요청 URL : /bbs/{articleId}
※ 파라미터로 처리 : @PathVariable("articleId") String articleId@Controller @RequestMapping("/bbs") public class BbsController{ // 자동으로 DI 해주는 어노테이션 @Autowird private BbsService service; // @RequestMapping("/{articleId}") public String viewDetail(@PathVariable String articleId){ Article article = service.viewArticle(articleId); return new ModelAdnView("/bbs/view_detail").addObject("article", article); } }
http://cafe.daum.net/sq99/2hq/68443 URL의 경우, 68443가 게시물의 번호입니다. Spring에서는 "/bbs/{articleId}" 이런식으로 정의하여 변수를 받을 수 있습니다. 메소드 파라미터에 @PathVariable 어노테이션 적어주고 변수 타입, 변수명 지정하면 변수명으로 URL로 넘어온 값을 접근하여 사용할 수 있습니다.
URL로 넘어온 변수를 처리하는 코드 예시입니다.
URL이 대충 "/bbs/{articleId}" 이렇게 넘어왔다고 가정해봅시다.
URL과 맞아 떨어지는 viewDetail()메소드가 실행되는데, 이 때 URL에 붙은 articleId값이 파라미터 변수로 넘어옵니다.
그리고 이런저런 코드 수행해서 return 하게 되는것입니다.
위 @PathVariable과 같은 역할을 하지만 URL 모양이 다릅니다.
@RequestParam은 "http://localhost:8070/bbs/write?author=hihihi"
이런식으로 "?"와 "="로 파라미터 값을 넘겼을 때 사용하는 어노테이션입니다.
- 응답으로 View(JSP)와 Model(Domain Object, VO)을 함께 처리할 때 사용
- 서비스로부터 받아온 데이터를 뷰로 전달해주는 역할
@Controller public class BbsController{ @Autowired private BbsService service; // @RequestMapping("/list") public ModelAndView list(){ //전체 게시물 보는 메소드 //service 객체를 통해 모든 기사 List형태로 가져오기 List<Article> articleList = service.getAllArticles(); //ModelAndView 객체 생성 ModelAndView view = new ModelAndView(); // bbs 디렉토리 밑에 list.jsp 파일 선택 view.setViewName("bbs/list"); //key-value 형태로 데이터 전달 view.addObject("articleList", list); // return view; } }
Controller에 의해서 적절한 모델을 호출하고 그로부터 결과값을 받았다고 가정해봅시다. 이제는 그 결과를 화면에 뿌려줘야합니다. view(jsp파일)와 모델(데이터) 모두를 전달해야합니다. 그럴 때 사용하는 게 ModelAndView입니다.
ModelAndView객체는 2개의 데이터가 있습니다. 1) ViewName, 2) Object입니다. ViewName은 파일 이름이라고 생각하시면 됩니다. Object는 데이터입니다.
- ModelAndView를 사용한 모델/뷰 처리 - View 작성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> ${helloMessage} </body> </html>
- 데이터 바인딩
* ${modelName}으로 표현
- 리다이렉트(포워드) 처리
- 컨트롤러에서 클라이언트의 요청을 처리한 후에 다른 페이지로 리다이렉트 하고 싶을 때 :
- return "redirect:/bbs/list";
- cf) forward : return "forward:/bbs/list";- 경로 부분이 "/"로 시작하면 웹 어플리케이션 내에서의 절대 경로로 리다이렉트
- "/"로 시작하지 않으면 현재 경로를 기준으로 상대 경로로 리다이렉트
return "redirect:/bbs/list"; 이렇게 코드를 쓰면, 저 URL에 해당하는 메소드를 매핑해줍니다.
- 아래 코드의 경우 "redirect:/header/main"과 동일한 URL로 리다이렉트
@ReuqestMapping("/header/createauth") public String createAuth(){ return "redirect:main"; }
- "redirect:" 뒤에 완전한 URL을 적으면, 해당 URL로 리다이렉트 된다.
@RequestMapping("/header/createauth") public String createAuth(){ return "redirect:http://localhost:8080/TotalTest"; }
1) BbsController를 작성하고 이 안에서 BbsService 클래스를 호출하는 식으로 구현하겠습니다.
2) HTTP 파라미터를 사용하는 예제도 해볼것입니다.
↑ controller 패키지에 Bbscontroller class를 생성할 겁니다.
↑ 클래스 레벨로 URL 매핑하기 위해 @RequestMapping 적고, 시스템 가동 시 dispatcherServlet이 scan 가능하도록 @Controller도 적습니다.
↑ BbsService 참조 변수를 선언하고 자동 DI가 되도록 @Autowired 추가합니다.
↑ /write URL 요청 시 응답할 메소드를 작성했습니다. 파라미터로 문자열 하나를 받을 건데 String형 author 변수가 받을 수 있도록 작성합니다.
↑ bbsservice 참조 변수를 통해 호출하는 메소드는 지난 포스팅에서 다뤘기 때문에 생략합니다.
↑ 파라미터 값을 성공적으로 받았는지 확인하기 위해 콘솔에 간단히 출력합니다.
↑ write_ok.jsp를 호출하기 위해 return 합니다.
↑ 간단한 write_ok.jsp 파일을 구현합니다.
↑ 내용은 알아서 작성해도 되지만, 파일 생성 경로는 꼭 지켜주셔야합니다.
지난 포스팅에서 web.xml에 작성했던 경로 그대로 파일을 생성해주세요. 그래야 dispatcherServlet이 찾아요...
↑ 서버 start 합니다.
↑ 크롬창에서 URL 직접 치고 GET 방식으로 파라미터 넘겨줍니다.
↑ 일단 jsp파일은 정상적으로 화면에 뿌려집니다. 콘솔에 파라미터 값이 제대로 print 됐는지도 확인해봐야 합니다.
↑ 제대로 값이 출력됐습니다.