2017-06-06 9 views
3

春にリクエストパラメータ用のBeanオブジェクトを持つ場合:Beanプロパティのエイリアスを定義する方法はありますか?Spring-mvcでリクエストパラメータのエイリアスを設定するには?

@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

が、私は使用することができます同様の注釈はありますか?私はあなたのための赤い長方形でそれをマークし

enter image description here

+0

この記事を調べましたか? https://dzone.com/articles/customizing-parameter-names –

+0

すぐに使えるものではありません。 –

答えて

0

は、私はあなたが、@RequestParam注釈のための春のドキュメントを見てみることができると信じて、ここにコピーされたスナップショットです。

パラメータが@RequestParam annotation内にあることが、エイリアスの目的であることがはっきりと分かります。

+0

'@ RequestParam'はメソッドでのみフィールドには適用されません! – membersound

0

セッターを使用することができます。あなたの例を考える:

@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は、パラメータ名をhyphenedますので、春が正常にそれらをバインドすることができ、フィルタを作成します。
  2. すべてのリクエストパラメータをコントローラ内の生のマップとして受信し、normalizeキーを入力してから、すべてのタイプ変換用のものを自分で投入します。

フィルタとオプションは、次のようになります。

@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)); 
     } 
    } 
} 

その前の例ではがあるよう動作するはずです。

2番目のオプションは、次のようになります。

@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(); 
    } 
} 

とラッパー:使用してカスタム名を設定することが可能であるとして、次のアプローチで

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

しかし、私がセッターの名前を変更した場合、プロパティ+ getter + setterの名前を完全に変更することもできます。しかし、それは私が望むものではありません。入力パラメータを "MY-INPUT"として送信する必要があるとします。 'my-input = test'のような設定子は無効な変数名です。このようなパラメータが可能な機能を提供したいと思います。 – membersound

+0

はい、フィールドとゲッターの名前を変更することはできますが、そうする必要はありません。 1つのプロパティに対して、必要な数だけセッターを配置することができます。ハイフンで区切られたパラメータ名については、私は答えを更新しました。 –

0

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)); 
    } 
} 

テストをアノテーション:

Bozhosの答え: How to customize parameter names when binding spring mvc command objects

私はスプリング4を使用しているので、カスタムリゾルバは次のように追加できます。

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

次のようにそれは、その後のGETクエリBeanで使用することができます。また、

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

、私もGETクエリが大文字小文字を区別しませんパラメータと一致するように好きなように、私は次のクラスを使用しています:

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

次のように配線することができる。

@Bean 
public CaseInsensitiveRequestFilter caseInsensitiveFilter() { 
    return new CaseInsensitiveRequestFilter(); 
} 
関連する問題