인생 디벨로퍼

json 응답 처리 (RESTful API) 본문

Project/Mini Project - Rodonin (구인구직)

json 응답 처리 (RESTful API)

뫄뫙뫄 2023. 3. 21. 19:43
728x90

기존에 만들어둔 구인구직 사이트를

모든 데이터를 dto 로 받아 json 으로 응답하되도록 변경해보자

 

스프링 프레임 워크에서 json 으로 응답했을때 장점이 뭘까?

  1. 가벼운 데이터 형식
    JSON은 XML 보다 가볍고 간단한 데이터 형식. 이는 데이터 전송 속도를 빠르게 하고, 처리 속도 향상 시킴
  2. 높은 호환성
    JSON은 거의 모든 프로그래밍 언어에서 사용할 수 있는 데이터. 다양한 프로젝트에서 쉽게 적용 가능.
  3. RESTful API와의 호환성
    RESTful API는 주로 JSON 형식의 데이터를 사용. 스프링 프레임워크에서는 RESTful API를 쉽게 구현할 수 있도록 JSON 형식의 데이터를 지.
  4. 객체 지향적인 데이터 형식
    JSON은 객체 지향적인 데이터 형식으로, 자바에서 사용하는 객체와 유사한 형식. 
  5. 간편한 파싱
    데이터를 쉽게 처리하고, 객체로 변환하여 사용할 수 있다.
  6. 쉬운 디버깅
    JSON은 읽기 쉽고, 이해하기 쉬운 형식을 가져 디버깅이 쉽다.

 => 데이터 전송 및 처리의 효율성, 호환성, RESTful API와의 호환성, 객체 지향적인 데이터 형식, 파싱 및 디버깅의 용이성 등의 이점을 제공!

 


Controller

@RequiredArgsConstructor
@RestController
public class AnnouncementController {

    public final AnnouncementService announcementService;

    @GetMapping("announcement/{id}")
    public ResponseEntity<?> detail(@PathVariable Integer id) {
        AnnouncementDetailOutDto datailDto = announcementService.공고상세보기(id);
        return new ResponseEntity<>(new ResponseDto<>(1, "공고상세보기페이지", datailDto), HttpStatus.OK);
    }
}

@RequiredArgsConstructor : 클래스 내부에 선언된 final 필드들을 초기화하는 생성자를 자동으로 생성


AnnouncementDetailOutDto

@Getter
@Setter
public class AnnouncementDetailOutDto {
    private Integer id;
    private CompanyDto company;
    private StackMasterDto stackMaster;
    private String announcementTitle;
    private String announcementContent;
    private String announcementCarrer;
    private String announcementHireType;
    private String announcementRecNum;
    private String announcementSalary;
    private String announcementArea;
    private Timestamp createdAt;

    @Getter
    @Setter
    public static class CompanyDto {
        private Integer id;
        private String companyFullname;
        private String companyCeoName;
        private String companyAddress;
        private String companyThumbnail;
        private Date companyEstablish;
        private Integer companyEmployeesNumber;
        private Timestamp createdAt;
    }

    @Getter
    @Setter
    public static class StackMasterDto {
        private Integer id;
        private String stackName;

    }
}


Repository

 public AnnouncementDetailOutDto findByIdJoinCompanyAndStack(int id);

Service

@RequiredArgsConstructor
@Service
public class AnnouncementService {

    public final AnnouncementRepository announcementRepository;

    @Transactional
    public AnnouncementDetailOutDto 공고상세보기(Integer id) {
        AnnouncementDetailOutDto detailDto = announcementRepository.findByIdJoinCompanyAndStack(id);
        return detailDto;
    }
}

xml

<resultMap id="datailResultMap" type="shop.mtcoding.rodongin.dto.announcement.AnnouncementDetailOutDto">
        <id property="id" column="id"/>
        <result property="announcementTitle" column="announcement_title"/>
        <result property="announcementContent" column="announcement_content"/>
        <result property="announcementCarrer" column="announcement_carrer"/>
        <result property="announcementHireType" column="announcement_hire_type"/>
        <result property="announcementRecNum" column="announcement_rec_num"/>
        <result property="announcementSalary" column="announcement_salary"/>
        <result property="announcementArea" column="announcement_area"/>
        <result property="createdAt" column="created_at"/>
        <association property="company" javaType="shop.mtcoding.rodongin.dto.announcement.AnnouncementDetailOutDto$CompanyDto">
            <id property="id" column="id"/>
            <result property="companyFullname" column="company_fullname"/>
            <result property="companyCeoName" column="company_ceo_name"/>
            <result property="companyAddress" column="company_address"/>
            <result property="companyThumbnail" column="company_thumbnail"/>
            <result property="companyEstablish" column="company_establish"/>
            <result property="companyEmployeesNumber" column="company_employees_number"/>
            <result property="createdAt" column="created_at"/>
        </association>
        <association property="stackMaster" javaType="shop.mtcoding.rodongin.dto.announcement.AnnouncementDetailOutDto$StackMasterDto">
            <id property="id" column="id"/>
            <result property="stackName" column="stack_name"/>
        </association>
    </resultMap>

    <select id="findByIdJoinCompanyAndStack" resultMap="datailResultMap">
      select *
        from announcement a
            inner join company c
            on a.company_id = c.id
            inner join STACK_MASTER  sm
            on a.STACK_ID =sm.ID 
        where a.id = #{id};
    </select>


ControllerTest

@Transactional 
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
public class AnnouncementControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void detail_test() throws Exception {
        // given
        int id = 1;

        // when
        ResultActions resultActions = mvc.perform(
                get("/announcement/" + id));
        String responseBody = resultActions.andReturn().getResponse().getContentAsString();
        System.out.println("테스트 : " + responseBody);
        // then

        resultActions.andExpect(jsonPath("$.code").value(1));
        resultActions.andExpect(status().isOk());
    }
}

getContentAsStrign() : HTTP 응답의 바디(body)를 문자열 형태로 반환하는 메서드. JSON, XML, HTML 등의 데이터 형식을 사용하는 REST API에서 자주 사용

jsonPath("$.code") : JSONPath 라이브러리를 사용하여 JSON 데이터에서 "code" 필드의 값을 추출

728x90