2015-01-22 1 views
0

기본 휴식 컨트롤러가 매개 변수를 가져 왔습니다.알 수없는 쿼리 매개 변수에 대해 봄 RestController를 확인하는 방법은 무엇입니까?

쿼리 문자열에 정의하지 않은 매개 변수가 포함되어 있으면 어떻게 연결을 거부 할 수 있습니까?

localhost:8080/myapp/123?pagggge=1

이 URL을 호출 할 때 현재 방법은 바로 ID로 실행되고, 미지의 paggge 매개 변수를 그냥 무시

@RestController 
@RequestMapping("/") 
public class MyRest { 
@RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    @ResponseBody 
    public String content(@PathVariable id, @RequestParam(value = "page", required = false) int page) { 
     return id; 
    } 
} 

. 어느 것이 일반적으로 괜찮지 만 어떻게 유효성을 검사하고 HTTP 상태 코드를 반환 할 수 있습니까? 메서드 매개 변수에

+0

의 라인을 따라 JSON 응답을 얻을 것이다? 매개 변수를 수락하지 않으면 바닥에 떨어 뜨리는 데 아무런 해가 없습니다. – Makoto

답변

1

추가 HttpServletRequest request는, 메소드 본문에

String query = request.getQueryString() 

을하고 그것을 확인합니다.

+0

유감스럽게도 쿼리 경로에'...? query = testvalue'가 포함 된 경우에만 쿼리가 설정되므로이 기능이 작동하지 않습니다 – membersound

+0

@ mememoundound hm, 오해의 소지가 있습니다. 메소드의'param'과'String query = request.getQueryString()'에서'HttpServletRequest request'를 사용하는 것은 어떨까요? – eis

+0

위대한, 그것을 몰랐다. 이 작품! – membersound

5

원하는대로 모든 매개 변수를 수신하고 처리 할 수 ​​있습니다. 인용 스프링 문서는 :

@RequestParam 주석이지도 < 문자열에 사용되는

, 문자열 > 또는 MultiValueMap < 문자열, 문자열 > 인수는,지도는 모든 요청 매개 변수로 채워집니다. 컨트롤러 방법에

+0

그게 최고의 정답입니다. – Jamby

1

, 당신은에 전달 된 모든 쿼리 매개 변수에 액세스하려면 유형 @RequestParam Map<String, String>의 인수를 포함 할 수 있습니다. 일반적인 ArgsChecker 서비스 클래스는 사용자가 잘못된 인수에 통과했는지 여부를 확인하는 데 사용할 수 있습니다. 그렇다면 @ControllerAdvice 클래스에서 처리 할 수있는 예외를 throw 할 수 있습니다.

@RestController 
@ExposesResourceFor(Widget.class) 
@RequestMapping("/widgets") 
public class WidgetController { 


@Autowired 
ArgsChecker<Widget> widgetArgsChecker; 

    @RequestMapping(value = "", method = RequestMethod.GET, produces = {"application/hal+json"}) 
    public HttpEntity<PagedResources<WidgetResource>> findAll(@RequestParam @ApiIgnore Map<String, String> allRequestParams, Pageable pageable, PagedResourcesAssembler pageAssembler) { 
     Set<String> invalidArgs = widgetArgsChecker.getInvalidArgs(allRequestParams.keySet()); 
     if (invalidArgs.size() > 0) { 
      throw new QueryParameterNotSupportedException("The user supplied query parameter(s) that are not supported: " + invalidArgs + " . See below for a list of query paramters that are supported by the widget endpoint.", invalidArgs, widgetArgsChecker.getValidArgs()); 

     } 

다음과 같이 ArgsChecker 정의 할 수 있습니다

package com.widgetstore.api.annotation; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Queryable { 
} 

은 이제 표시 :은 "@Queryable"주석이되는 분야를 찾기 위해 반사를 사용

import com.widgetstore.api.annotation.Queryable; 
import lombok.Getter; 
import org.apache.commons.lang3.reflect.FieldUtils; 

import java.lang.reflect.Field; 
import java.util.HashSet; 
import java.util.Set; 
import java.util.stream.Collectors; 

public class ArgsChecker<T> { 
    @Getter 
    private Set<String> validArgs; 

    private ArgsChecker(){}; 

     public ArgsChecker(Class<T> someEntityClass){ 
    validArgs= FieldUtils.getFieldsListWithAnnotation(someEntityClass,Queryable.class) 
      .stream() 
      .map(Field::getName) 
      .collect(Collectors.toSet()); 
    validArgs.add("page"); 
    validArgs.add("size"); 

} 

public Set<String> getInvalidArgs(final Set<String> args){ 
    Set<String> invalidArgs=new HashSet<>(args); 
    invalidArgs.removeAll(validArgs); 
    return invalidArgs; 



    } 
    } 

, 도메인 클래스의 입력란에 문의 할 수있는 내용은 입니다.

이제

ArgsChecker 콩이 응용 프로그램 시작에 생성되어 있는지 확인 :

package com.widgetstore.api.exception; 


import org.springframework.http.HttpStatus; 
import org.springframework.http.ResponseEntity; 
import org.springframework.web.bind.annotation.ControllerAdvice; 
import org.springframework.web.bind.annotation.ExceptionHandler; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.ResponseBody; 

import java.util.Date; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.Map; 

@ControllerAdvice 
@RequestMapping(produces = "application/json") 
@ResponseBody 
public class RestControllerAdvice { 


    @ExceptionHandler(QueryParameterNotSupportedException.class) 
    public ResponseEntity<Map<String,Object>> unrecogonizedParameter(final QueryParameterNotSupportedException e){ 
     Map<String,Object> errorInfo = new LinkedHashMap<>(); 
     errorInfo.put("timestamp",new Date()); 
     errorInfo.put("errorMessage",e.getMessage()); 
     errorInfo.put("allowableParameters",e.getValidArgs()); 
     return new ResponseEntity<Map<String, Object>>(errorInfo,HttpStatus.BAD_REQUEST); 
    } 



} 
: 마지막으로

@SpringBootApplication 
public class StartWidgetApi{ 

public static void main(String[] args){ 
    SpringApplication.run(StartWidgetApi.class); 
} 


@Bean(name="widgetArgsChecker") 
public ArgsChecker<Widget> widgetArgsChecker(){ 
    return new ArgsChecker<Widget>(Widget.class); 
} 

//Other ArgsCheckers of different types may be used by other controllers. 
@Bean(name="fooArgsChecker") 
public ArgsChecker<Foo> fooArgsChecker(){ 
    return new ArgsChecker<Foo>(Foo.class); 
} 
} 

,

응용 프로그램에서 발생한 예외를 수신하는 @ControllerAdvice 클래스를 정의

, QueryParameterNotSupportedException을 정의하십시오.

import lombok.Getter; 

import java.util.Set; 

@Getter 
public class QueryParameterNotSupportedException extends RuntimeException{ 
    private Set<String> invalidArgs; 

    private Set<String> validArgs; 

    public QueryParameterNotSupportedException(String msg, Set<String> invalidArgs, Set<String> validArgs){ 
     super(msg); 
     this.invalidArgs=invalidArgs; 
     this.validArgs=validArgs; 
    } 

} 

이제 사용자가/위젯을 때리면?someUnknownField = ABC & someOtherField = XYZ 그는 내가 왜 상관이야 ... 알고 싶습니다

{"timestamp": 2017-01-10'T'blahblah, "errorMessage": "The user supplied query parameter(s) that are not supported: ["someUnknownField","someOtherField"]. See below for a list of allowed query parameters." , 
"allowableParameters": ["productGuid","serialNumber"] 
} 
관련 문제