본문 바로가기

SpringBoot

ch2 11. @RequestMapping과 URL인코딩

1. @RequestMapping대신 @GetMapping, @PostMapping 사용 가능 

@Controller
public class LoginController {
//    @RequestMapping(value = "/login/login", method = RequestMethod.GET) // 아래와 같다. 기본은 GET
//    @RequestMapping("/login/login") // 더 짧게 아래 문장과 같이 사용 가능
    @GetMapping("/login/login")
    public String showLogin() {
        return "login"; // login.html
    }

    //  하나의 메소드로 GET, POST 둘 다 처리하는 경우
    //    @RequestMapping(value = "/login/login", method = {RequestMethod.POST,RequestMethod.GET})
    //    @RequestMapping(value = "/login/login", method = RequestMethod.POST) // 아래와 같다.
    @PostMapping("/login/login")
    public String login(String id, String pwd, Model model) throws Exception{
        // 1. id, pwd를 확인
        if(loginCheck(id,pwd)) {
		// ... 
	}

원래 @RequestMapping은 

@RequestMapping(value = "/login/login", method = RequestMethod.GET)

이렇게 요청한 메소드가 GET인지 POST인지 정해주며, 코드가 길다. 

디폴트는 GET으로 생략 가능하지만, POST일 경우에는 디폴트가 아니기 때문에 생략이 불가능하다.

@RequestMapping(value = "/login/login", method = RequestMethod.POST)

하지만 코드가 너무 길어지게 된다. 

 

 그래서 위 코드를 짧게 사용하기 위해 @GetMapping, @PostMapping을 사용한다. 

위 코드와 똑같이 작동하며 요청에 따라 @GetMapping, @PostMapping을 사용해주면 된다. 

 

IF) GET, POST를 하나의 메소드로 처리한다면?

@RequestMapping(value = "/login/login", method = {RequestMethod.GET, RequestMethod.POST})

그러면 이 메소드가 요청이 GET이나 POST일 때 둘 다 처리하게 되는 것이다. 
다른 경우에는 분리해서 사용하지만, 기본적으로는 둘 다 GET으로 오든 POST로 오든 한 메소드가 처리한다. 
분리해서 사용할 경우 짧게 @GetMapping, @PostMapping으로 처리해주면 된다. 

 

예제는 /login/login으로 같은 URL을 맵핑하지만, 원래는 메소드마다 다른 URL을 맵핑한다. 

같아도 되는 이유는 GET, POST 메소드가 달라서이다. 

URL이 같아도 메소드가 다르면 서버가 요청을 구별할 수 있다. 

 

 

2. 클래스에 붙이는 @RequestMapping

- 맵핑될 URL의 공통 부분을 @RequestMapping으로 클래스에 적용

@Controller
@RequestMapping("/login")
public class LoginController {
// 	@RequestMapping(value = "/login/login", method = RequestMethod.GET)
    @GetMapping("/login")
    public String showLogin() {
        return "login"; // login.html
    }

// 	@RequestMapping(value = "/login/login", method = RequestMethod.POST)
    @PostMapping("/login")
    public String login(String id, String pwd, Model model) throws Exception{
        // 1. id, pwd를 확인
        if(loginCheck(id,pwd)) {
		// ... 
	}

이전에는 @RequestMapping을 메소드 앞에 작성해서 메소드 단위로 붙였는데, 
메소드의 공통 부분을 따로 떼서 클래스 앞에 붙이는 것이다. 

그러면 메소드에 똑같이 들어가는 부분 /login을 공통적으로 사용할 수 있다. 

실제로 컨트롤러가 등록될 때 어떤 URL을 어떤 메소드가 처리하는지를 다 등록한다. 
그 때  @RequestMapping("/login")의 /login과  @GetMapping("/login")의 /login이 합쳐져서 /login/login이렇게 된다.

 

로그인 기능과 관련된 메소드들을 LoginController에 만들어두고, 하나의 로그인 모듈을 클래스로 정의하고 
클래스 안에 관련된 기능 메소드들을 모아놓는다. 

모듈 이름을 @RequestMapping으로 클래스 적용해주고, 나머지 URL들은 모듈명을 제외한 나머지 경로만 
적어주게 할 수 있는 기능이다. 

 

 

3. URL 인코딩 - 퍼센트 인코딩

- URL에 포함된 non-ASCII문자를 문자 코드(16진수) 문자열로 변환

브라우저가 한글을 16진수로 자동변환해서 보내준다. 

그러면 서버 쪽에서 이걸 받아서 

request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");

받은 데이터가 UTF-8이라는걸 지정해주고, 그 다음에 name을 읽어야 원래 데이터로 바뀐다. 

 

 

 

4. URL Rewriting

- URL을 변경하는 것. 주로 URL에 쿼리 스트링을 추가

            String msg = URLEncoder.encode("id 또는 패스워드가 일치하지 않습니다.", "utf-8");
            return "redirect:/login/login?msg=" + msg;

기본적인 URL놔두고 뒤에 쿼리 스트링으로 다른 정보를 추가하는 것이다. 
redirect는 항상 GET요청이고, 위 URL로 요청을 하는데 거기에 어떤 정보를 같이 보내고자한다. 

그러면 쿼리스트링으로 보내고 싶은 데이터를 붙여주면 된다. 
이 때 추가하려는 메시지가 한글이 포함되어 있다면 직접 URL Encoding을 진행해주어야 한다. 

(이건 브라우저를 통해 입력한 것이 아니기 때문에 수동으로 진행)