Продолжая предыдущую запись в блоге о конструкторе и параметрах метода и 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.