2016-05-20 4 views
1

Можно ли изменить значения @RequestMapping при запуске?Изменение @RequestMappings при запуске

В принципе, я хочу создать аннотацию @Api(Api.Version.V1), что означает, что отображение запроса должно быть изменено с /api/dogs на /api/v1/dogs. Я хочу сделать это как на уровне класса (применимо ко всем), так и на уровне метода (повторное использование контроллера из более ранней версии и его изменение).

Я мог бы жестко закодировать это, но это оставляет много строк, чтобы заботиться, и это не так чисто, как я хочу.

Так можно (используя bpp или что-то подобное) изменить изменения запроса во время запуска? после того, как были созданы бобы, я не хочу/их изменять.

Я также изучал RequestCondition, но это похоже на более динамичный характер, и я не уверен, что это поможет мне в этом случае.

Еще одна проблема, я хотел бы, чтобы можно было аннотировать два класса с одним и тем же сопоставлением запросов (и затем аннотацию переписать его), и я уверен, что это нужно делать при начальной загрузке контекста (так что мы надеваем 'получать дубликаты и т. д.).

Любые указатели в правильном направлении будут оценены.

Edit:

Got это почти работает, я использую пользовательский RequestMappingHandlerMapping и переопределение метода getMappingForMethod, который позволяет мне получить аннотаций (на обоих типов и метода) и возвращает модифицированный RequestMappingInfo с добавлены пути.

Один вопрос остается, даже если я удалю все старые сопоставления и вернусь только /api/v1/dogs старое сопоставление /api/dogs все еще работает. Можно ли как-то удалить это отображение?

Код здесь, если кому-то интересно.

@Component 
public class CustomRequestMappingHandlerMapping 
    extends RequestMappingHandlerMapping 
{ 
    @Override 
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) 
    { 
     RequestMappingInfo info = super.getMappingForMethod(method, handlerType); 

     ApiVersion methodApiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class); 
     ApiVersion typeApiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class); 

     if (typeApiVersion == null) 
     { 
      return info; 
     } 

     Set<String> oldPatterns = info.getPatternsCondition().getPatterns(); 
     Set<String> patterns = new HashSet<>(); 

     for (String p : oldPatterns) 
     { 
      for (int v = 0; v < typeApiVersion.value().length; v++) 
      { 
       ApiVersion.Version version = typeApiVersion.value()[v]; 

       if (!p.startsWith(version.getValue())) 
       { 
        if (p.startsWith("/")) patterns.add("/" + version.getValue() + p); 
        else patterns.add("/" + version.getValue() + "/" + p); 
       } 
       else 
       { 
        patterns.add(p); 
       } 
      } 
     } 

     PatternsRequestCondition patternsRequestCondition = new PatternsRequestCondition(
      patterns.toArray(new String[]{}), null, null, true, true, null); 

     RequestMappingInfo mappingInfo = new RequestMappingInfo(
      null, patternsRequestCondition, info.getMethodsCondition(), info.getParamsCondition(), info.getHeadersCondition(), info.getConsumesCondition(), 
      info.getProducesCondition(), info.getCustomCondition() 
     ); 

     return mappingInfo; 
    } 
} 
+0

Проблема была, что я использовал '' который также регистрирует по умолчанию 'RequestMappingHandlerMapping ', поэтому там был конфликт. – mortenoh

ответ

1

Вы можете динамически добавлять requestMappings либо реализации HandlerMapping интерфейса или расширения AbstractUrlHandlerMapping.

Идея заключается в том создать свой собственный обработчик Mapping вместо того, чтобы использовать реализацию по умолчанию, такие как SimpleUrlHandlerMapping,DefaultAnnotationHandlerMapping и т.д.

Смежные вопросы