1.  AJax와 JASON : 댓글 기능 구현 

기존 작업한 게시판에 댓글 기능을 구현
클라이언트는 Ajax(Axios 라이브러리) · 서버는 RESTful · JPA는 다대일 방식으로 구현


(1)  Ajax와 REST 방식의 이해

 

1)  Ajax Asynchronous JavaScript And XML


  💫  Ajax 방식은 브라우저에서 서버를 호출하지만 모든 작업이 브라우저 내부에서 이루어지기 때문에 현재 브라우저의 브라우저 화면 변화 없이 서버와 통신할 수 있음

 

    ✓  실제 구현은 자바 스크립트를 이용해서 XML을 주고 받는 방식을 이용
    ✓  최근에는 JSON을 이용하는 방식을 더 선호. 스프링 부트는 Springweb을 추가하면 자동으로 관련 라이브러리를 받음

  💫  클라이언트 중심의 개발

    ✓  Ajax가 가져온 변화는 모바일에서도 Ajax 방식으로 데이터를 교환할 수 있기 때문에 활용이 커짐
    ✓  모바일에서도 일반 웹과 마찬가지로 서버의 데이터가 필요한데 이때 화면과 관련된 부분은 필요하지 않기 때문에 서버에서 순수한 데이터만 전송하는 방식이라면 클라이언트의 구현이 웹 / 앱에 관계없이 데이터를 재사용할 수 있음

 

 

2)  JSON 문자열

 

    📍 "서버에서 순수한 데이터를 보내고 클라이언트가 적극적으로 이를 처리한다"라는 개발 방식에서 핵심은 '문자열'

  • '문자열'은 어떠한 프로그래밍 언어나 기술에 종속되지 X
  • 문자열을 이용하면 데이터를 주고 받는 것에 신경 써야 하는 일은 없지만, 문자열로 복잡한 구조의 데이터를 표현하는데 문제가 발생
  • 문자열로 복잡한 데이터를 표현하기 위해서 고려되는 것이 XML과 JSON 이라는 형태.
  • JSON은 자바스크립트 문법에 맞는 문자열로 데이터를 표현하기 때문에 클라이언트에서 어떤 기술을 이용하든 공통적으로 인식할 수 있음
  • 스프링 부트 역시 JSON 관련 라이브러리 jackson-databind가 이미 포함되어 있으므로 별도의 설정 없이 바로 JSON 데이터를 만들어 낼 수 있음

 

3)  REST 방식

 

  💫  html이 아니라 json or xml 형식이 response에 사용

    ✓  REST 방식은 클라이언트 프로그램인 브라우저나 앱이 서버와 데이터를 어떻게주고 받는 것이 좋을지에 대한 가이드
    ✓  예전의 웹 개발 방식에서는 특정한 URL이 원하는 '행위나 작업'을 의미하고, GET / POST 등은 데이터를 전송하는 위치를 의미
      Ajax를 이용하면 브라우저의 주소가 이동할 필요 없이 서버와 데이터를 교환할수 있기 때문에 URL은 '행위나 작업'이 아닌 '원하는 대상' 그 자체를 의미하고, GET / POST 방식과 PUT / DELETE 등의 추가적인 전송방식을 활용해서 '행위나 작업'을 의미하게 됨

 

이전 표현 REST 방식 표현
/board/modify  ▶️  게시물의 수정 (행위 / 목적)
<form>  ▶️  데이터의 묶음
 /board/123  ▶️  게시물 지원 자체
PUT 방식  ▶️  행위나 목적



4)  REST 방식의 URL 설계

Method URI 의미 추가 데이터
GET /board/123 123번 게시물 조회  
POST /board/ 새로운 게시물 등록 신규 데이터 게시물
PUT /board/123 123번 게시물 수정 수정에 필요한 데이터
DELETE /board/123 123번 게시물 삭제  

 

 

5) springdoc-openapi 준비

 

  ⚡️  REST 방식의 테스트는 특별한 화면을 구성하는 것이 아니라 데이터를 전송하고 결과를 확인하는 방법
          ➡️  예를 들어 브라우저는 GET 방식의 데이터를 확인할 때는 유용하지만 POST 방식으로 데이터를 처리할 때는 상당히 불편하고, 사용자도 측정한 경로를 어떻게 호출하는지 알 수 없으므로 상세한 정보를 전달하기 어려운 단점이 있음
  ⚡️  REST 방식을 이용할 때는 전문적으로 API를 테스트 할 수 있는 Postman이나 springdoc-openapi 등을 이용

 

Swagger UI
  • 부트 2까지는 Swagger UI를 사용. 부트 3부터는 Swagger UI사용이 안되고 springdoc-openapi를 지원
  • openapi는 개발할 때 어노테이션 설정으로 API 문서와 테스트 할 수 있는 화면을 생성할 수 있으므로 개발자는 한번에 테스트 환경까지 구성할 수 있다는 장점이 있음

(2)  프로젝트의 준비

1)  modelMapper 설정 변경

  • RootConfig의 modelMapper 설정을 변경. STRICT ▶️ LOOSE로 변경
@Configuration
public class RootConfig {
    @Bean
    public ModelMapper getMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
            .setFieldMatchingEnabled(true)
            .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
            .setMatchingStrategy(MatchingStrategies.LOOSE);
       return modelMapper;
    }
}

 

 

2) bulid.gradle 설정 추가

  • 프로젝트의 bulid.gradle 파일에 'OpenAPI Starter WebMVC UI'으로 검색한 라이브러리를 추가
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

 

  • 서버 실행을 하고 아래 주소로 접근
    http://localhost:8080/swagger-ui/index.html

 

3) Config 클래스 추가

  • 프로젝트의 config 패키지에 SpringdocOpenapiConfig 클래스를 추가
  • 일반 컨트롤러와 REST 컨트롤러를 분리해서 설정
  • 경로에 /api가 포함된 컨트롤러의 경우에는 REST API로 인식
  • 경로에 /api가 포함안된 컨트롤러의 경우에는 COMMON API로 인식
@Configuration
public class SpringdocOpenapiConfig {

    @Bean
    public GroupedOpenApi restApi() {
        return GroupedOpenApi.builder()
                .pathsToMatch("/api/**")
                .group("REST API")
                .build();
    }

    @Bean
    public GroupedOpenApi commonApi() {
        return GroupedOpenApi.builder()
                .pathsToMatch("/**/*")
                .pathsToExclude("/api/**/*")
                .group("COMMON API")
                .build();
    }
}

 

SampleJasonController 경로 수정
@Log4j2
@RestController
public class SampleJSONController {

    @GetMapping("/api/helloArr")
    public String[] helloArr() {
        log.info("HelloArr...");

        return new String[] {"AAA", "BBB", "CCC"};
    }
}

SampleController에 @Operation 추가
@Operation(summary = "hello")
@GetMapping("/hello")
public void hello(Model model) {
    log.info("hello...");
    model.addAttribute("msg", "Hello World");
}

@Operation(summary = "ex/ex1")
@GetMapping("/ex/ex1")
public void ex1(Model model) {
    List<String> list = Arrays.asList("AAA", "BBB", "CCC", "DDD");

    model.addAttribute("list", list);
}


 

  ⚡️  현재 설정은 기본적으로 가장 많이 사용하는 패키지를 기반으로 패키지의 모든 클래스에 대해서 API 테스트 환경을 만들어 냄

 

 

 

 ✓  화면의 board-controller를 선택하면 다음과 같이 메서드를 선택할 수 있는 화면이 나옴

✓  특정한 메서드를 선택하고 'Try it out' 버튼을 클릭하면 파라미터를 입력할 수 있음

✓  파라미터를 입력하고 'Execute'를 클릭하면 아래에서 결과 화면을 볼수 있음

 

 

 

 

 

 

 

정적 파일 경로 문제


  ✓  Swagger UI 설정이 끝나면 기존에 동작하던 /board/list/ 에는 문제가 생길 수 있음

  ✓  이 문제를 해결하려면 Spring Web 관련 설정을 추가해 주어야만 함
  ✓  config 폴더에 CustomServletConfig 클래스를 추가

 

  • 클래스에 @EnableWebMvc 어노테이션을 추가하는 것이 가장 중요
  • Swagger UI 가 적용되면서 정적 파일의 경로가 달라졌기 때문인데 이를 CustomServletConfig로 WebMvcConfigurer 인터페이스를 구현하도록하고 addResourceHandlers를 재정의해 수정
@Configuration
@EnableWebMvc
public class CustomServletConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/");
        registry.addResourceHandler("/fonts/**").addResourceLocations("classpath:/static/fonts/");
        registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/");
        registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/static/assets/");
    }
}

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts