Я пытаюсь изменить значение аннотации RequestMapping во время выполнения для метода HTTP GET - привет (который возвращает простую строку) внутри класса обслуживания отдыха - SpringRestController .
Значение uri, определенного в аннотации @RequestMapping для метода hello, равно "/ hello / {name}" . Я могу изменить значение аннотации во время выполнения на "hi / {name}" , используя отражение в конструкторе класса SpringRestController.
Я могу проверить измененное значение, напечатав значение аннотации внутри метода init, аннотированного аннотацией @PostConstruct, а также внутри другого контроллера. Однако, когда я пытаюсь получить доступ к методу GET в браузере: с измененным значением - http://localhost: 9090 / пружинный ботинок-упор / отдых / привет / Pradeep ( не работает )
с исходным значением - http://localhost: 9090 / пружинный ботинок-отдых / отдых / привет / Pradeep ( отлично работает )
Я ожидаю, что метод HTTP GET hello будет доступен с использованием измененного значения пути во время выполнения - "/ hi / {name}" вместо исходного значения пути - "/ hello / {name}" . PS - Это требование для нас, и оно должно быть сделано таким образом, чтобы значение @RequestMapping можно было настраивать извне без изменений в исходном коде. Вот код - SpringRestController. java
package com.example.spring.rest.controller;
import javax.annotation.PostConstruct;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.spring.rest.custom.annotations.ConfigurableRequestMapping;
import com.example.spring.rest.reflection.ReflectionUtils;
@RestController
@RequestMapping("/rest")
public class SpringRestController {
public SpringRestController() {
RequestMapping rm = SpringRestController.class.getAnnotation(RequestMapping.class);
System.out.println("Old annotation : " + rm.value()[0]);
RequestMapping rmNew = new ConfigurableRequestMapping("/rest");
ReflectionUtils.alterAnnotationValueJDK8_v2(SpringRestController.class, RequestMapping.class, rmNew);
RequestMapping rmModified = SpringRestController.class.getAnnotation(RequestMapping.class);
System.out.println("Constructor -> New annotation : " + rmModified.value()[0]);
}
@RequestMapping(value = "/hello/{name}")
public String hello(@PathVariable String name) {
System.out.println("Name : " + name);
return "Hello " + name;
}
@PostConstruct
private void init(){
System.out.println("Annotations initialization post construct.");
RequestMapping rmModified = SpringRestController.class.getAnnotation(RequestMapping.class);
System.out.println("Init method -> New annotation : " + rmModified.value()[0]);
}
}
Код для изменения значения аннотации -
ReflectionUtils. java
package com.example.spring.rest.reflection;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.spring.rest.controller.SpringRestController;
import com.example.spring.rest.custom.annotations.ConfigurableRequestMapping;
import com.example.spring.rest.utils.PropertyReader;
public class ReflectionUtils {
@SuppressWarnings("unchecked")
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){
Object handler = Proxy.getInvocationHandler(annotation);
Field f;
try {
f = handler.getClass().getDeclaredField("memberValues");
} catch (NoSuchFieldException | SecurityException e) {
throw new IllegalStateException(e);
}
f.setAccessible(true);
Map<String, Object> memberValues;
try {
memberValues = (Map<String, Object>) f.get(handler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
Object oldValue = memberValues.get(key);
if (oldValue == null || oldValue.getClass() != newValue.getClass()) {
throw new IllegalArgumentException();
}
memberValues.put(key,newValue);
return oldValue;
}
}