簡體   English   中英

將@RequestParam 轉換為自定義對象

[英]Convert @RequestParam to custom Object

優化搜索請求時遇到問題。 我有在 url 查詢中接受參數的搜索方法,例如:

http://localhost:8080/api?code.<type>=<value>&name=Test

Example: http://localhost:8080/api?code.phone=9999999999&name=Test

定義 SearchDto:

public class SearchDto {

    String name;    
    List<Code> code;

}

定義代碼類:

public class Code {

    String type;    
    String value;

}

目前我正在使用 Map<String,String> 作為方法的傳入參數:

@GetMapping("/search")
public ResponseEntity<?> search(final @RequestParam Map<String, String> searchParams) {
  return service.search(searchParams);
}

然后手動轉換 SearchDto 類的映射值。 是否可以擺脫 Map<String,String> 並將 SearchDto 作為控制器方法中的參數直接傳遞?

在查詢字符串中傳遞 json 實際上是一種不好的做法,因為它會降低安全性並限制您可以發送到端點的參數數量。

從技術上講,您可以通過使用 DTO 作為控制器的參數,然后在將 json 發送到后端之前對 json 進行 URL 編碼來使一切正常。

在您的情況下,最好的選擇是提供一個監聽 POST 請求的端點:在執行搜索時使用 POST 既不是錯誤,也不是壞習慣。

你可以自定義一個HandlerMethodArgumentResolver來實現它。

但是,如果你想讓一個對象接收傳入的參數。 為什么不使用 POST

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Example {
}
public class ExampleArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        Example requestParam = parameter.getParameterAnnotation(Example.class);
        return requestParam != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

        ResolvableType resolvableType = ResolvableType.forMethodParameter(parameter);

        Map<String, String[]> parameterMap = webRequest.getParameterMap();
        Map<String, String> result = CollectionUtils.newLinkedHashMap(parameterMap.size());
        parameterMap.forEach((key, values) -> {
            if (values.length > 0) {
                result.put(key, values[0]);
            }
        });

        //here will return a map object.  then you convert map to your object, I don't know how to convert , but you have achieve it.
        return o;
    }

}

添加到容器

@Configuration
@EnableWebMvc
public class ExampleMvcConfiguration implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new ExampleArgumentResolver());
    }
}

用法

@RestController
public class TestCtrl {


    @GetMapping("api")
    public Object gg(@Example SearchDto searchDto) {
        System.out.println(searchDto);
        return "1";
    }

    @Data
    public static class SearchDto {
        String name;
        List<Code> code;
    }

    @Data
    public static class Code {
        String type;
        String value;
    }
}

這是一個演示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM