Статьи

Имена параметров метода и Spring

Продолжая предыдущую запись в блоге о конструкторе и параметрах метода и Java, не сохраняющих имена параметров во время выполнения — предыдущая запись была о конструкторе, не сохраняющем имена параметров, и о последствиях этого для инъекций Contructor в Spring, здесь я расскажу еще несколько Сценарии, в которых имена параметров не сохраняются, имеют значение для Spring:

1. Рассмотрим метод Spring MVC Controller с параметром для привязки к параметру запроса, который передается в:

1
2
3
4
5
@RequestMapping(value='/members/find')
 public String getMembersByName(@RequestParam String name){
  ...
  return 'list';
 }

Здесь с параметром «name» связана аннотация @RequestParam, которая указывает Spring Spring на привязку параметра запроса «name» к этому параметру метода.

Поскольку имя параметра не сохраняется во время выполнения, вполне вероятно, что Spring вызовет исключение:

1
2
Request processing failed; nested exception is java.lang.IllegalArgumentException: Name for argument type  not available, and parameter name i
nformation not found in class file either.

Исправление здесь простое: либо скомпилировать с параметрами отладки, в которых будут сохранены имена параметров во время выполнения, либо лучше просто указать, какое имя параметра запрашиваемого запроса, в качестве аргумента аннотации @RequestParam:

1
2
3
4
@RequestMapping(value='/members/find')
public String getMembersByName(@RequestParam('name') String name){
 return 'list';
}

2. В том же ключе рассмотрим другой метод контроллера Spring MVC, на этот раз поддерживающий шаблоны URI:

1
2
3
4
@RequestMapping(value='/members/{id}', method=RequestMethod.GET)
public @ResponseBody Member get(@PathVariable Integer id){
 return this.memberDB.get(id);
}

Здесь ожидается, что если запрос приходит с URI / members / 20, то параметр id будет связан со значением 20, однако, так как во время выполнения имя параметра ‘id’ не сохраняется, исправление, как в предыдущем случае это либо для компиляции с включенной отладкой, либо для явного упоминания в аннотации @PathVariable, что такое ожидаемое имя шаблона

1
2
@RequestMapping(value='/members/{id}', method=RequestMethod.GET)
public @ResponseBody Member get(@PathVariable('id') Integer id){

3. Третий пример — поддержка кэширования в Spring с аннотацией @Cacheable . Рассмотрим пример метода с аннотацией @Cacheable:

1
2
3
4
@Cacheable(value='default', key='#param1.concat('-').concat(#param2)')
public String cachedMethod(String param1, String param2){
    return '' + new Random().nextInt();
}

Здесь ключ является выражением Spring-EL, которое инструктирует генератору ключей генерировать ключ, комбинируя аргумент первого параметра имени param1 с аргументом второго параметра с именем param2. Однако проблема, как и прежде, заключается в том, что эти имена недоступны во время выполнения.

Как и раньше, одним из исправлений является компиляция с включенными символами отладки. Второе исправление заключается в использовании заполнителей для замены индекса параметра — a0 ИЛИ p0 для первого параметра, a1 ИЛИ p1 для второго параметра и т. Д. Таким образом, ключ @Cacheable будет выглядеть следующим образом:

1
2
3
4
@Cacheable(value='default', key='#p0.concat('-').concat(#p1)')
public String cachedMethod(String param1, String param2){
    return '' + new Random().nextInt();
}

Итак, в заключение, безопасный способ использовать функции Spring, которые зависят от имен параметров метода, — это скомпилировать с помощью debug on (-g или -g: var option of javac) или явно передавая мета-информацию, которая указывает, какие имена параметров находятся в во время выполнения.

Ссылка: Имена параметров метода и Spring от нашего партнера JCG Биджу Кунджуммена из блога all and sundry.