2017-06-06 2 views
3

Wenn ein Bean-Objekt für Request-Parameter im Frühjahr vorhanden ist: Gibt es eine Möglichkeit, einen Alias ​​für eine Bean-Eigenschaft zu definieren?Wie Alias ​​für Anforderungsparameter in Spring-mvc festlegen?

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

Natürlich @RequestParam nicht funktioniert, aber ist es eine ähnliche Anmerkung ich verwenden könnte?

+0

Haben Sie diesen Artikel durchgesehen? https://dzone.com/articles/customizing-parameter-names –

+0

Nicht out-of-the-box. –

Antwort

0

Ich glaube, Sie können, für @RequestParam Annotation einen Blick auf Frühling Dokumentation nehmen, hier ist eine kopierte snapshot:

enter image description here

ich es für Sie in einem roten Rechteck markiert.

Sie können deutlich sehen, dass der value Parameter in @RequestParam Annotation für Alias ​​Zwecke ist.

+0

'@ RequestParam' ist nicht anwendbar auf Feld, nur auf Methode! – membersound

0

Sie können Setter dafür verwenden. Gegeben Ihr Beispiel:

@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 + '}'; 
     } 
    } 
} 

Und Anrufer verwenden könnte:

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

aktualisieren

Nun, wenn Sie mit Bindestrich-Namen Parameter zu tun Dinge werden ein wenig schwieriger.

Grundsätzlich können Sie:

  1. einen Filter machen, die werden normalize hyphened Parameternamen, so Feder kann sie erfolgreich binden.
  2. Empfangen Sie alle Anfrageparameter als eine rohe Karte in Ihrem Controller, normalize Schlüssel und dann füllen Sie das Objekt mit allen Arten von Conversion-Zeug von selbst.

Eine Option mit Filter könnte wie folgt aussehen:

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

Mit diesem vorherigen Beispiel sollte arbeiten als ist.

könnte die zweite Option sein:

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

Und die Verpackung:

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

Testing:

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

Nun, aber wenn ich den Setter umbenenne, könnte ich auch die Eigenschaft + Getter + Setter vollständig umbenennen. Aber das will ich nicht. Stellen Sie sich vor, der Eingangsparameter sollte als "MY-INPUT" gesendet werden. Ein Setter wie 'my-input = test' ist ein ungültiger Variablenname. Obwohl ich ein Feature bereitstellen möchte, wo solche Parameter möglich sind. – membersound

+0

Ja, Sie können Feld und Getter auch umbenennen, aber Sie müssen nicht. Sie können so viele Setter für eine Eigenschaft haben, wie Sie möchten. Wie für die Hypen-getrennte Parameternamen - Ich habe eine Antwort aktualisiert. –

0

Mit dem folgenden Ansatz eine ist es möglich, benutzerdefinierte Namen setzen mit Anmerkung:

Siehe Antwort von Bozhos: How to customize parameter names when binding spring mvc command objects

Da ich Feder 4 verwende, kann der benutzerdefinierte Resolver wie folgt hinzugefügt werden.

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

Es kann dann auf der get-Abfrage Bean wie folgt verwendet werden:

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

Ferner kann, wie Ich mag auch die Abfrageparameter get entsprechen Groß- und Kleinschreibung, ich die folgende Klasse mit:

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

Es kann wie folgt verdrahtet werden:

@Bean 
public CaseInsensitiveRequestFilter caseInsensitiveFilter() { 
    return new CaseInsensitiveRequestFilter(); 
} 
Verwandte Themen