알쓸전컴(알아두면 쓸모있는 전자 컴퓨터)

Spring GetMapping Pageable multiple Sort,복잡한 ObjectMapping 을 axios query 보내는 방법 본문

Web /Spring Framework tip

Spring GetMapping Pageable multiple Sort,복잡한 ObjectMapping 을 axios query 보내는 방법

백곳 2022. 9. 22. 11:09

Spring 을 사용할때 Pageable을 사용하면 multiple sort 를 하려면 

sort query를 위와 같이 적용해서 보내 주어야 한다.

 

하지만 axios에서 

 

const { data } = await axios.get("/test", {
    params: {
    	page: 0,
    	sort: ["testColumn1,asc","testColumn2"],
    },
})

 

위처럼 보내면

http://127.0.0.1:8181/test?page=0&sort[]=testColumn1,asc&sort[]=testColumn2

http://127.0.0.1:8181/test?page=0&sort[]=testColumn1,asc&sort[]=testColumn2

 

위처럼 쿼리가 나가서 Spring Controller 에서  Pageable  객체를 받을때 Sort 부분이 정상적으로 처리 되지 않습니다. 

 

그래서 

axios 에서 보낼때 

https://www.npmjs.com/package/qs 해당 라이브러리를 사용 합니다, 

 

npm install --save qs

 

typesciprt 사용할 경우 type package 도 설치 해 줍니다. 

npm install --save-dev @types/qs

 

 

await axios.get("/elmItem/items", {
	params: {
    	page: 0,
    	sort: ["testColumn1,asc","testColumn2"],
    },
    paramsSerializer: params => {
        return qs.stringify(params,{ indices: false })
    }
})

http://127.0.0.1:8181/test?page=0&sort=testColumn1,asc&sort=testColumn2

위와 같이 axios 에서 보내게 됩니다. 

 

그럼 Spring 의 Pageable 객체에서 multiple Sort을 정상적으로 받아 들이게 됩니다. 

 

추가적으로 

 

@GetMapping("/items")
Page<ElmItemResDto> getItems(ElmItemFilterReqDto filter, Pageable pageable){
    return elmItemService.getItems(filter, pageable);
}

 

이렇게 콘트롤러가 있다고 가정 하고 

 

@Data
public class ElmItemFilterReqDto {
    String area;
    Flags flag;
    String investmentPart;
    Duration investDateDuration;
    Scheduler scheduler;
    String processPart;
}
@Data
public class Flags {
    Boolean investDateDuration;
    Boolean investMoneyDuration;
    Boolean scheduleDuration;
    Boolean notComplete;
}
@Data
public class Duration {

    @DateTimeFormat(pattern = "yyyy/MM/dd")
    LocalDate from;

    @DateTimeFormat(pattern = "yyyy/MM/dd")
    LocalDate to;
}
@Data
public class Scheduler {
    String type;
    String column;
    Duration duration;
}

위와 같이 get으로 복잡한 Object을 Mapping 한다고 했을때 

 

http://127.0.0.1:8181/elmItem/items?area=&flag.investDateDuration=false&flag.investMoneyDuration=false&flag.scheduleDuration=false&flag.notComplete=false&investmentPart=&investDateDuration.from=2019/09/23&investDateDuration.to=2022/09/23&scheduler.type=Plan&scheduler.column=eqpWarehousing&scheduler.duration.from=2019/09/23&scheduler.duration.to=2022/09/23&processPart=&page=0&sort=enter,asc&sort=cool,desc

 

axios 에서는 위와 같이 필드의 경로는 dot(.) 으로 Depth(안으로) 을 들어가 줘야 합니다.

 

async getItems(): Promise<PageWrap<ElmItemResDto>> {
    const { data } = await axios.get("/elmItem/items", {
        params: {
            area: "",
            flag:{
                investDateDuration: false,
                investMoneyDuration: false,
                scheduleDuration: false,
                notComplete: false
            },
            investmentPart: "",
            investDateDuration: {
                from: "2022/09/21",
                to: "2022/09/21",
            },
            scheduler: {
                type: "Plan",
                column: "eqpWarehousing",
                duration: {
                    from: "2022/09/21",
                    to: "2022/09/21",
                }
            },
            processPart: ""
        },
        paramsSerializer: params => {
            return qs.stringify(params,{ indices: false, allowDots: true })
        }
    })
    return data;
}

       paramsSerializer: params => {
               return qs.stringify(params,{ indices: false, allowDots: true })
       }

 

paramsSerializer 을 위와 같은 옵션으로 지정해 주면 Spring Controller 에서 정상 적으로 매핑 되게 됩니다. 

 

한동한 삽질을 했기에 해당 자료를 작성해 둡니다. 

 

참고로 allowDtos 옵션을 안주었을때는

 

http://127.0.0.1:8181/elmItem/items?area=&flag[investDateDuration]=false&flag[investMoneyDuration]=false&flag[scheduleDuration]=false&flag[notComplete]=false&investmentPart=&investDateDuration[from]=2022/09/21&investDateDuration[to]=2022/09/21&scheduler[type]=Plan&scheduler[column]=eqpWarehousing&scheduler[duration][from]=2022/09/21&scheduler[duration][to]=2022/09/21&processPart=

 

위와 같이 [] 로 구분 되는데 다른 Web BackEnd FrameWork 에서는 위와 같이 처리해 주면 Mapping 을 해주는 프로토콜이 있는 것으로 추측 됩니다. 뇌피셜 입니다.. 

 

Comments