강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

유승현님의 프로필 이미지
유승현

작성한 질문수

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

HTTP 요청 - 기본, 헤더 조회

queryParam이 없는 경우, 여러개 있는경우 (multivaluedMap 사용) 관련질문

작성

·

1.1K

0

수업에서 같은 키를 가진 쿼리 파라미터가 여러개인 경우

MultiValueMap을 쓰면 된다고 하셔서 적용해 봤는데요

같은 리소스에 대해

1. 파라미터가 없는 경우

2. 같은 파라미터가 여러개(1개이상)인 경우

Q1) 이 2가지를 적용하고자 하면 아래와 같이 하면될까요?

Q2) @RequestParam(required=false) 설정 했음에도 쿼리 파라미터를 넣지 않으면 nullpoint에러가 떠,

@Nullable을 추가하였는데 이 방법이 맞는건가요?

---

Status 에 맞는 조건에 따라 결과 값을 출력해주고 싶은건데 

a. 스테이터스가 없으면 전체 list 출력

b. 스테이터스가 있으면 해당하는 (ex> new, reserved) status에 해당하는 list 출력

-----

같은 리소스에 대해 요청을 받는거라면 한 method내에 있는게 맞는 것 같아 이렇게 코딩하였는데

MultiValueMap을 사용하고 requestParam에 false를 주어

파라미터 가 없는 경우를 처리하려 했으나

정의한 status enum값에 없는 쿼리 파라미터를 넣었을 때 예외 처리 작업, jpa에서 in절 사용 에 넣어줄 파라미터 값으로 변환 작업 등 (이전에 jpa수업에서 질문하였을때, 순수 jpa로 연습하라하셔서 순수 jpa로 연습중) 으로

controller내에서 로직이 너무 길게 있는것 같아, 좋은 방법이 아닌것 같습니다. 

Q2) MultiValueMap외에 같은 파라미터를 여러개 받을수 있는 방법이 있을까요?

Q3) url 경로는 contoller와 밀접한 거라 controller로직내에 작성하였는데 이런 경우면 service로직에 넣어주는게 맞을까요?

답변주시면 감사드리겠습니다.

private final String[] STATUS_PARAMS = {"new", "complete", "reserve"};
private final String GET_ALL_POST_PARAM_KEY = "status";
@ApiImplicitParams({
@ApiImplicitParam(name = "status", required = false ,dataTypeClass = String.class, paramType = "query"),
@ApiImplicitParam(name = "status", required = false ,dataTypeClass = String.class, paramType = "query"),
@ApiImplicitParam(name = "status", required = false ,dataTypeClass = String.class, paramType = "query")
})
@GetMapping()
public GetAllPostResponseDto getAllPost(
@ApiIgnore @RequestParam(required = false) @Nullable MultiValueMap<String, String> statuses,
@ApiIgnore HttpSession session){

getSessionCheckedAccount(session);

if (statuses.size() == 0){
List<Post> posts = postService.findAll();
return new GetAllPostResponseDto(posts);
}

boolean keyMatch = !statuses.keySet().stream().allMatch(GET_ALL_POST_PARAM_KEY::equals);
boolean statusMatch = !Arrays.asList(STATUS_PARAMS).containsAll(statuses.get(GET_ALL_POST_PARAM_KEY));

if(keyMatch || statusMatch){
throw new IllegalArgumentException("잘못된 경로 입니다.");
}

List<PostStatus> postStatuses = statuses.get(GET_ALL_POST_PARAM_KEY)
.stream().map(String::toUpperCase)
.map(PostStatus::valueOf)
.collect(toList());

List<Post> posts = postService.findAllByStatuses(postStatuses);
return new GetAllPostResponseDto(posts);

}
public List<Post> findAllByStatuses(List<PostStatus> postStatuses){
return em.createQuery("select p from Post p" +
" join fetch p.seller s" +
" join fetch p.postCategory pc" +
" join fetch pc.category c" +
" where p.postStatus in (:statuses)", Post.class)
.setParameter("statuses", postStatuses)
.getResultList();
}

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 유승현님

다음 코드를 참고해주세요.

http://localhost:8080/params?value=a&value=b

package com.example.springmvcaccpet;


import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Slf4j
@RestController
public class ParamsController {

@GetMapping("/params")
public String params(@RequestParam(value = "value", required = false) List<String> values) {
for (String value : values) {
System.out.println("value = " + value);
}
return "test";
}

}

url 경로에 대한 부분은 컨트롤러나 인터셉터에서 처리하는 것이 맞습니다.

감사합니다.

유승현님의 프로필 이미지
유승현

작성한 질문수

질문하기