如何在Spring-mvc中为请求参数设置别名?

时间:2017-06-06 12:45:46

标签: java spring spring-mvc

在spring中为请求参数设置bean对象时:有没有办法为bean属性定义别名?

@RestController
public class MyServlet {
   @GetMapping
   public void test(MyReq req) {
   }
}

public class MyReq {
   @RequestParam("different-name") //this is invalid
   private String name;
   private int age;
}

当然@RequestParam不起作用,但我可以使用类似的注释吗?

5 个答案:

答案 0 :(得分:1)

请求参数由设置器绑定。您可以使用原始参数名称添加一个额外的设置器。像这样:

public class MyReq {
   private String name;
   private int age;

   public void setDifferentName(String differentName) {
      this.name=differentName;
   }
}

注意:仅当您的参数为驼峰式(例如differentName=abc)时,它才有效。不适用于different-name=abc

答案 1 :(得分:0)

您可以使用setter。举个例子:

@SpringBootApplication
public class So44390404Application {

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

    @RestController
    public static class MyServlet {
        @GetMapping
        public String test(MyReq req) {
            return req.toString();
        }
    }

    public static class MyReq {
        private String name;
        private int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setDifferent_Name(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "{" + name + age + '}';
        }
    }
}

来电者可能会使用:

$so44390404 curl -XGET 'http://localhost:8000?name=adam&age=42'          
{adam42}%
$so44390404 curl -XGET 'http://localhost:8000?Different_Name=John&age=23'
{John23}% 

<强>更新

好吧,如果你正在处理连字符命名的参数,事情会变得有点棘手。

基本上你可以:

  1. 制作一个过滤器,其normalize个参数名称为normalize,因此spring可以成功绑定它们。
  2. 在控制器中接收所有请求参数作为原始地图,@Component public static class CustomRequestParametersFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { filterChain.doFilter(new RequestParameterNormalizerWrapper(request), response); } public static class RequestParameterNormalizerWrapper extends HttpServletRequestWrapper { public static final String HYPHEN = "-"; private final Map<String, String[]> parameterMap = new HashMap<>(); public RequestParameterNormalizerWrapper(HttpServletRequest request) { super(request); for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) { if (entry.getKey().contains(HYPHEN)) { parameterMap.put(normalize(entry.getKey()), entry.getValue()); } else { parameterMap.put(entry.getKey(), entry.getValue()); } } } private String normalize(final String key) { if (key.contains(HYPHEN)) { return WordUtils.capitalizeFully(key, HYPHEN.charAt(0)).replaceAll(HYPHEN, ""); } return key; } @Override public Map<String, String[]> getParameterMap() { return Collections.unmodifiableMap(this.parameterMap); } @Override public Enumeration<String> getParameterNames() { return Collections.enumeration(this.parameterMap.keySet()); } @Override public String getParameter(String name) { return super.getParameter(normalize(name)); } @Override public String[] getParameterValues(String name) { return parameterMap.get(normalize(name)); } } } 键,然后自行填充所有类型转换内容的对象。
  3. 带过滤器的选项可能如下所示:

    @RestController
    public static class MyServlet {
    
        @GetMapping
        public String test(@RequestParam Map<String, String> pvs) {
            final MyReq req = new MyReq();
            final BeanWrapper beanWrapper = new HyphenAwareBeanWrapper(req);
            beanWrapper.setPropertyValues(pvs);
            return req.toString();
        }
    }
    

    前面的例子应该

    第二个选项可能是:

    public static class HyphenAwareBeanWrapper extends BeanWrapperImpl {
        public static final String HYPHEN = "-";
    
        public HyphenAwareBeanWrapper(Object object) {
            super(object);
        }
    
        @Override
        public void setPropertyValues(Map<?, ?> map) throws BeansException {
            final ArrayList<PropertyValue> propertyValueList = new ArrayList<>(map.size());
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                final String key = entry.getKey().toString().contains(HYPHEN)
                        ? WordUtils.capitalizeFully(entry.getKey().toString(), HYPHEN.charAt(0)).replaceAll(HYPHEN, "")
                        : entry.getKey().toString();
                propertyValueList.add(new PropertyValue(key, entry.getValue()));
            }
            super.setPropertyValues(new MutablePropertyValues(propertyValueList));
        }
    }
    

    包装器:

    $ curl -XGET 'http://localhost:8000?name=John&age=42'
    {John42}%
    $ curl -XGET 'http://localhost:8000?different-name=John&age=42'
    {John42}%
    

    测试:

    __init__.py

答案 2 :(得分:0)

使用以下方法,可以使用注释设置自定义名称:

见Bozhos答案: How to customize parameter names when binding spring mvc command objects

当我使用弹簧4时,可以按如下方式添加自定义旋转变压器。

df_avg <- df %>% 
    summarise(dist_m = sum(dist_m, na.rm = TRUE), 
              time_s = sum(as.integer(time_s), na.rm = TRUE), 
              speed_m_per_s = dist_m / time_s)

df_avg
#> # A tibble: 2 x 4
#>      ID   dist_m time_s speed_m_per_s
#>   <int>    <dbl>  <int>         <dbl>
#> 1     1 66473.76    120      553.9480
#> 2     2 35647.18    120      297.0598

然后可以在get查询bean上使用它,如下所示:

@Configuration
public class AdapterConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new AnnotationServletModelAttributeResolver(false));
    }
}

此外,由于我还希望匹配不区分大小写的get查询参数,我使用以下类:

https://github.com/mdeinum/spring-utils/blob/master/src/main/java/biz/deinum/web/filter/CaseInsensitiveRequestFilter.java

可以按如下方式连接:

@SupportsCustomizedBinding
public class MyReq {
   @CommandParameter("different-name") //this is valid now!
   private String name;
}

答案 3 :(得分:0)

类似于Sergiy Dakhniy / Bohdan Levchenko的评论。请求参数由设置器绑定。您可以从传入请求中添加一个带有参数名称的附加设置器。像这样:

@GetMapping(value = "/do-something")
public ResponseEntity<String> handleDoSomething(@Valid MyReq myReq) {
...
}
public class MyReq {
  private String name;

  public void setDifferent_name(String name) {
    this.name = name;
  }
}

例如:http://www.example.com/do-something?different_name=Joe

答案 4 :(得分:-1)

我相信你可以看看Spring文档中的@RequestParam注释,这是一个复制的快照:

enter image description here

我为你标记了一个红色矩形。

您可以清楚地看到value注释中的@RequestParam参数仅用于别名。