본문 바로가기

Study/개발일지

[백엔드온라인TIL] java 학습 16일차

오늘 공부내용

1. spring 컨텐츠 개념
2. @RestController 어노테이션 

3. jackson 라이브러리 사용

4. jdbcTemplate 

정적 컨텐츠

정적 컨텐츠란?

  • 서버에 저장되어 있고 변화 없이 브라우저로 뿌려지는 컨텐츠(파일)
  • 요청에 따라 응답만을 수행

Spring Boot는 정적 컨텐츠 기능 자동 제공

 https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html#boot-features-spring-mvc-static-content

  • /static 폴더에서 정적 컨텐츠를 찾아서 제공한다.

/static  hello-static.html 을 생성 및 작성해보자.

MVC와 템플릿 엔진

템플릿 엔진이란?

  • 서버에서 동적으로 파일을 바꿔서 브라우저로 뿌려주는 엔진
  • jsp, php 등이 있다.
  • 이를 위해 필요한 Model, View, Controller를 합쳐 MVC라고 한다.
  • 예전에는 View만으로 개발을 진행했다면, 이제는 View는 화면을 그리는 데에만 집중하고, Model & Controller는 Business logic과 관련있거나, 내부적인 것들을 처리하는데 집중하기 위해 이를 분리하였다.
    • !면접 질문!
      • 유지보수성
      • 애플리케이션의 확장성
      • 유연성 증가(클라이언트의 새로운 요구사항에 대해 최소한의 비용으로 보다 유연하게 대처)
      • 중복코딩의 문제점 감소
    • 그렇지 않으면 유지, 보수에 엄청난 시간이 필요할 것이다 ...

정적 컨텐츠와 다른 점
서버에서 뿌려질 컨텐츠에 동적으로 변화를 줄 수 있다.

이번에는 MVC를 이용하여 Parameter를 받는 Controller를 생성해보자.

controller/HelloController.java

@GetMapping("hello-mvc")
public String helloMvc(@RequestParam ("name") String name, Model model) {
    model.addAttribute("name", name);
    return "hello-template";
}
  • @RequestParam annotation은 HTTP request parameter를 method의 parameter로 전달받을 때 사용한다. form 에서의 input  name 과 매칭되어 해당 값을 받아올 수 있다.
  • String name 에 해당 값을 담고, Model model 을 이용하여 View 에서 rendering 시 사용
  • model.addAttribute method로 key  "name"이고, 변수이름  name 인 값을 가져와서 View 로 전달한다.

resources/templates/hello-templates.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
    <p th:text="'hello' + ${name}">hello! empty</p>
</body>
</html>
  • xmlns:th="~"  thymeleaf 템플릿을 사용함을 명시
    • thymeleaf의 장점은, 위와 같이 저장한 파일 자체를 서버없이 열어도 해당 파일의 소스코드를 그대로 확인 가능하다.
    • 서버가 동작하게 되면, th:text 에 있는 값으로 hello! empty 가 치환된다.

서버를 동작시켜 http://localhost:8080/hello-mvc 로 접속

WARN 51004 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'name' for method parameter type String is not present]
  • 위와 같은 log와 함께 Error page가 나오는 것을 확인할 수 있다. 쉽게 말해 name parameter에 아무것도 넘겨주지 않아서 뜨는 에러라고 할 수 있다.
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam (name = "name") String name, Model model) {
    model.addAttribute("name", name);
    return "hello-template";
}
  • 위와 같이, parameter의 이름을 명시하고, required option은 기본값이 true 이므로 그대로 둔다.

이제 http://localhost:8080/hello-mvc?name=spring 으로 접속해보자.

  • 동작방식은,
    1. url에서 받아온 name에 대한 "spring" 이라는 값이 public Stirng helloMvc  String name 에 담기고,
    2. model.addAttribute 를 통해 name  model 에 담겨, hello-template 으로 return
    3. ${name} 으로, model 에서 key값이 name 인 값을 가져와서 치환!

API

  • JSON 이라는 데이터 포맷으로 서버에서 클라이언트로 데이터를 전송하는 방식
@GetMapping("hello-string")
@ResponseBody
public String helloString(@RequestParam("name") String name) {
    return "hello" + name;
}
  • @ResponseBody 는, http에서의 body에 해당 내용을 직접 넣겠다는 의미!
  • Template engine과 다른 점은 "view" 개념 없이 data가 그대로 보여진다.
    • 확인하기 위해, http://localhost:8080/hello-string?name=spring 으로 접속하면, 아래와 같은 화면이 보이고, 페이지 소스 보기 하면, html code 없이 Data만 존재하는 것을 확인할 수 있다.

다음 예제는 Hello 객체와 getName & setName, 그리고 객체를 return 하는 Api 방식이다.

@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
    Hello hello = new Hello();
    hello.setName(name);
    return hello;
}

static class Hello {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


@RestController : Controller 중 View로 응답하지 않고 HttpResponse로 응답하는 Controller

@ResponseBody역할을 자동적으로 수행

@RequestMapping : Spring Controller 또는 그 메서드의 URI 정의 시 사용

요청을 받는 형식이 Get, Post, Patch, Put, Delete 를 정의하기도 함(default Get)

@PathVariable : URI에서 / 다음으로 넘어오는 값들을 파싱

 "/something/{id}"

@RequestBody : Post, Put, Patch로 요청을 받을 때, 요청에서 넘어온 Body값들을 자바 타입으로 파싱

@RequestParam : key value 형식의 파라미터를 파싱

 ?name=cristoval

@ResponseBody : HttpMessageConverter를 이용하여 JSON 혹은 xml로 요청에 응답

 RestController annotation이 적용된 Controller라면 적용할 필요가 없음

 

jackson 라이브러리 사용 


public class JacksonTest {


@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);
}

// lombok을 써서 객체에 @Getter가 있어야함 , 직렬화과정이 필요
@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());
}
}

JdbcTemplate의 소개

 

JdbcTemplate는 SQL Mapper의 종류로 스프링에서 SQL을 직접 사용하는 경우에 매우 좋은 선택지가 될 수 있다.

이는 spring-jdbc 라이브러리에 포함되어 있기 때문에 별도의 설정 없이 스프링으로 jdbc를 사용할 때 기본으로 사용되는 라이브러리이다.

 

기존 순수하게 jdbc 다루는 코드에는 수많은 반복 문제가 발생하는데 jdbcTemplate은 이를 템플릿 콜백 패턴을 통해 해결한다. 

 

순수 JDBC를 사용함에 따라 문제의 여지가 될 수 있는 부분들은 다음과 같다.

 

  • 커넥션을 획득하는 부분이 코드에 중복된다.
  • 사용한 리소스를 반환하기 위한 코드가 중복된다.
  • 트랜잭션 시작을 위한 코드가 반복된다.
  • 트랜잭션 시 커넥션을 동기화하기 위한 코드가 필요하다.
  • 특정 구현체에 종속된 예외를 발생시킨다.

다만 JdbcTemplate은 동적 SQL을 해결하기 어렵다. 

 

주요 기능

  • JdbcTemplate
    순서 기반 파라미터 바인딩 지원
  • NamedParameterJdbcTemplate
    이름 기반 파라미터 바인딩 지원
  • SimpleJdbcInsert
    Insert sql에 대한 편리한 기능 제공
  • SimpleJdbCall
    스토어드 프로시저를 편리하게 호출 가능

 

JdbcTemplate의 설정

 

spring-jdbc 패키지 내부에 존재하기 때문에 관련 라이브러리를 추가해야 한다.

728x90