FrameWork/Spring

Controller

jheaon 2024. 5. 16. 10:50

 

 

오늘은 Spring Controller을 다루는 법에 대해서 정리해보고자 한다. 

 


 

Controller

MVC 패턴과 내용이 이어집니다 참고하세요 :)

 

MVC Pattern

오늘은 Spring MVC 패턴에 대해 알아보고자 한다.    Spring MVC흔히 말하는 MVC 패턴이란 Model-Veiw-Controller의 약자로, 소프트웨어 디자인 패턴 중 하나를 의미한다.    Model : 데이터와 비즈니스 로

jheaon.tistory.com

 

Spring Controller에서 정적페이지와 동적페이지를 처리할 수 있다.

 

 

정적페이지

정적페이지 같은 경우 말 그대로 html을 그대로 클라이언트에게 넘겨주는 경우이다. SpringBoot서버에 html파일을 요청하면 해당 html 파일을 static 폴더에서 찾아서 반환해 준다. 

 

그냥 html 파일을 컨트롤러를 통해 반환 할 필요는 없지만 (예: localhost:8080/hello.html 처럼 접근하면 됨) 만약 컨트롤러를 거쳐서 html을 반환 해야 할 경우에는 redirect을 이용하여 처리가 가능하다. 

@GetMapping("/html/redirect")
public String htmlStatic() {
    return "redirect:/hello.html";
}

 

 

 

동적페이지

동적페이지 같은 경우 다음과 같은 과정을 거친다. 

  • 클라이언트 요청을 컨트롤러에서 모델로 처리
  • 템플릿 엔진에게 뷰, 모델 전달
  • 템플릿엔진에서 뷰에 모델을 적용하여 동적 . 웹페이지를 생성
  • 클라이언트에게 전달

 

다음은 컨트롤러와 Html 파일을 이용한 동적 페이지 처리 코드이다. 클라이언트 요청을 모델로 받고, 방문 횟수를 visits : visitCount을 추가하여 넘겨준다.

 

Controller.java

private static long visitCount = 0;

...

@GetMapping("/html/dynamic")
public String htmlDynamic(Model model) {
    visitCount++;
    model.addAttribute("visits", visitCount);
    return "hello-visit";
}

 

 

hello-visit.html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Hello Spring</title></head>
<body>
  <div>
    Hello, Spring 동적 웹 페이지!!
  </div>
  <div>
    (방문자 수: <span th:text="${visits}"></span>)
  </div>
</body>
</html>

 

 

 

 

JSON

요즘은 프론트 엔드, 백엔드가 각각 따로 발전하게 되면서 느슨한 결합의 개발을 많이 진행하게 되었고, 서버가 직접 뷰(html, css, js)를 반환하기보다는 요청에 맞는 특정한 정보만 반환하는 것을 선호하게 되었다. 따라서 요즘은 서버에서 JSON 형태의 데이터를 반환하는 식으로 많이 개발되고 있다. 

 

Spring에서는 JSON 데이터를 반환하는 방법에 2가지를 제시하고 있다. 

주의해야 할점 : 템플릿 엔진이 적용된 SpringBoot에서는 Controller에서 문자열을 반환하면 templates 폴더에서 해당 문자열의 html파일을 찾아서 반환해 주기 때문에, JSON데이터를 반환하고 싶다면 @ResponseBody 애너테이션을 추가해줘야 한다. 

알아두면 좋은 점 : 만약 각 메서드마다 @ReponseBody을 추가하기 귀찮다면, 클래스에서 @RestController(@Controller + @ResponseBody)을 사용해서 처리할 수 있다.

 

 

1. String으로 반환

Java는 JSON 타입을 지원하지 않기 때문에 JSON 형태의 String 타입으로 변환해서 사용해야 한다.

@GetMapping("/json/string")
@ResponseBody
public String helloStringJson() {
    return "{\"name\":\"Robbie\",\"age\":95}";
}

 

 

2. 자바 클래스를 반환

자바 객체를 JSON으로 변환하며, 이는 Spring에서 자동으로 Java객체를 JSON으로 변환해준다. 

@GetMapping("/response/json/class")
@ResponseBody
public Star helloClassJson() {
    return new Star("Robbie", 95);
}

 

 

 

 

 

Jackson

Jackson 라이브러리는 JSON 데이터 구조를 처리해주는 라이브러리이다. 객체를 JSON 타입의 String으로 혹은 그 반대 과정도 변환이 가능하다. Spring 3.0 버전 이후로는 Jackson과 관련된 API을 제공하고 있어 따로 JSON 데이터를 처리하지 않아도 자동으로 처리해 준다. 

 

  • 객체를 json으로 변환
@Test
@DisplayName("Object To JSON : get Method 필요")
void test1() throws JsonProcessingException {
    Star star = new Star("Robbie", 95);

    ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
    String json = objectMapper.writeValueAsString(star);

    System.out.println("json = " + json);
}

 

 

  • Json을 객체로 변환
@Test
@DisplayName("JSON To Object : 기본 생성자 & (get OR set) Method 필요")
void test2() throws JsonProcessingException {
    String json = "{\"name\":\"Robbie\",\"age\":95}"; // JSON 타입의 String

    ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper

    Star star = objectMapper.readValue(json, Star.class);
    System.out.println("star.getName() = " + star.getName());
}

 

 

 

 

 

 

Path Variable와 Request Param

클라이언트에서 서버로 HTTP 요청을 보낼 때 데이터를 함께 보낼 수 있다. 보내는 방식이 여러가지가 있는데 대표적으로 아래와 같이 존재한다. 

 

  • Path Variable

서버에 보내려는 데이터를 URL 경로에 추가해서 보내는 방식이다. (예 : http://localhost:8080/hello/request/star/Robbie/age/95)

 

해당 데이터를 받기 위해서는 /star/{name}/age/{age} 처럼 URL 경로에서 데이터를 받고자 하는 위치의 경로에 {data} 중괄호를 사용한다. 그리고 해당 요청 메서드 파라미터에 @pathVariable 애너테이션과 {name} 줄광호에 선언한 변수명과 변수타입을 선언하면 해당 경로의 데이터를 받을 수 있다. 

// [Request sample]
// GET http://localhost:8080/hello/request/star/Robbie/age/95
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
    return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
}

 

 

 

  • Request Param

서버에 보내려는 데이터를 URL 경로 마지막에 ?, & 을 사용하여 추가하는 방식이다. (예 :? name=Robbie&age=95)

 

@RequestParam 애너테이션과 함께 key 부분에 선언한 변수명, 변수타입을 선언하면 데이터를 받아 올 수 있다.

// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam String name, @RequestParam int age) {
    return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}

 

 

 

 

  • form 태그 POST

HTML의 form태그를 사용하여 POST 방식으로 HTTP 요청을 보낼 수 있다.

<form method="POST" action="/hello/request/form/model">
  <div>
    이름: <input name="name" type="text">
  </div>
  <div>
    나이: <input name="age" type="text">
  </div>
  <button>전송</button>
</form>

 

이때 데이터는 HTTP Body에 name=Robbie&age=95 형태로 담겨서 서버로 전달된다.

// [Request sample]
// POST http://localhost:8080/hello/request/form/param
// Header
//  Content type: application/x-www-form-urlencoded
// Body
//  name=Robbie&age=95
@PostMapping("/form/param")
@ResponseBody
public String helloPostRequestParam(@RequestParam String name, @RequestParam int age) {
    return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}

 

 

 

 

 

 

 

 

HTTP 데이터를 객체로 처리하는 방법

 

  • @ModelAttribute 
// [Request sample]
// POST http://localhost:8080/hello/request/form/model
// Header
//  Content type: application/x-www-form-urlencoded
// Body
//  name=Robbie&age=95
@PostMapping("/form/model")
@ResponseBody
public String helloRequestBodyForm(@ModelAttribute Star star) {
    return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}

 

HTML의 form 태그를 사용하여 POST 방식으로 HTTP 요청을 보낼 수 있다. 이때 해당 데이터는 HTTP Body에 name=Robbie&age=95 형태로 담겨 서버로 전달된다고 가정한다. 여기서 해당 데이터를 @ModelAttribute 애너테이션을 이용하면 Body 데이터를 Star star처럼 선언된 객체로 받아 올 수 있다.

 

 

  • Query String

?name=Robbie&age=95 처럼 데이터가 두개만 있다면 괜찮지만 여러 개 있다면 @RequestParam 애너테이션으로 하나씩 받기에는 코드가 지저분해 질 수 있다. 여기서 @ModelAtrribute 애너테이션을 사용한다면 Java의 객체로 데이터를 받아 올 수 있다.

// [Request sample]
// GET http://localhost:8080/hello/request/form/param/model?name=Robbie&age=95
@GetMapping("/form/param/model")
@ResponseBody
public String helloRequestParam(@ModelAttribute Star star) {
    return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}

 

 

  • @RequestBody

HTTP Body에 JSON 데이터를 담아 서버에 전달할 때 해당 Body 데이터를 Java의 객체로 전달 받을 수 있다. 

// [Request sample]
// POST http://localhost:8080/hello/request/form/json
// Header
//  Content type: application/json
// Body
//  {"name":"Robbie","age":"95"}
@PostMapping("/form/json")
@ResponseBody
public String helloPostRequestJson(@RequestBody Star star) {
    return String.format("Hello, @RequestBody.<br> (name = %s, age = %d) ", star.name, star.age);
}

 

@ModelAttribute을 사용할 때에는 해당 객체 필드에 데이터를 넣어주기 위해, set or get 메서드 또는 오버로딩된 생성자가 필요하다. 

'FrameWork > Spring' 카테고리의 다른 글

IoC, DI 컨테이너  (0) 2024.05.27
Thymeleaf  (0) 2024.05.21
JDBC (내용 추가 예정)  (0) 2024.05.20
MVC Pattern  (0) 2024.05.14
[Spring] Spring boot 프로젝트 생성하기  (1) 2023.06.23

'FrameWork/Spring'의 다른글

  • 현재글 Controller

관련글