2017-04-06 58 views
5

Mam kontroler rozruchu sprężyn, jednym z moich parametrów jest Enum. Wyliczenie ma wartość ciągu. Chciałbym jako parametr przekazać wartość enumu i kontrolera, by dać mi Enum. Czy można to zrobić?Spring Boot Controller - parametr Enum jako wartość

@RequestMapping(value = "/") 
public MyResponse getResponse (@RequestParam(value = "version") final ProjectVersion version) { 
    ...bla bla bla... 
} 

public enum ProjectVersion { 
    VERSION_1 ("1.00") 
    VERSION_2 ("2.00") 

    private final String version; 

    ProjectVersion (String version) { 
     this.version = version; 
    } 

    @Override 
    public String toString() { 
     return this.version; 
    } 

} 

Chcę, aby móc złożyć wniosek w następujący sposób:

http://myhost.com/mypath?version=1.00

I dostać w sterowniku ProjectVersion.VERSION_1

Jakieś pomysły?

+0

Tak, z niestandardowym serializatora. Zobacz to, dokładnie twój przypadek: http://stackoverflow.com/questions/7766791/serializing-enums-with-jackson –

+1

Jeśli przekażesz 'VERSION_1' to zadziała, jeśli przekażesz wartość wewnętrzną to nie będziesz wtedy trzeba samemu stworzyć niestandardowy konwerter. –

Odpowiedz

5

Nie jest to możliwe bez zmian. Musisz utworzyć niestandardowy konwerter, aby przekonwertować go z String na ProjectVersion.

Na przykład pierwszy określa konwerter od A String do ProjectVersion:

public class ProjectVersionConverter implements ConditionalGenericConverter { 

    @Override 
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { 
    return targetType.getType().equals(ProjectVersion.class); 
    } 

    @Override 
    public Set<ConvertiblePair> getConvertibleTypes() { 
    return Collections.singleton(new ConvertiblePair(String.class , ProjectVersion.class)); 
    } 

    @Override 
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 
    return ProjectVersion.findByVersion((String)source); 
    } 
} 

następnie zarejestrować go:

@Configuration 
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { 

    @Override 
    public void addFormatters(FormatterRegistry registry) { 
    registry.addConverter(new ProjectVersionConverter()); 
    } 
} 

Można pominąć rejestrację jeśli zdefiniować ProjectVersionConverter posiada sprężynę Bean. (Ten kod nie był testowany).

+0

Użycie przelicznika argumentów to czystsze i lepsze podejście. – digz6666

+0

Nie zgadzam się. Konwerter nie powinien przejmować się, że wartość jest przekazywana jako parametr żądania lub jako zmienna ścieżki. Dopóki używana jest odpowiednia adnotacja, z agnostycznym konwerterem, powinna działać. –

1

Bo trzeba przejść (na każde żądanie) argument do metody Controller, czyste rozwiązaniem byłoby wykorzystanie HandlerMethodArgumentResolver, tak że Wiosna pojemnik może dynamicznie wstrzykiwać ProjectVersion argument do metody kontrolera jak pokazano poniżej :

ProjectVersionArgumentResolver klasa:

public class ProjectVersionArgumentResolver implements 
            HandlerMethodArgumentResolver { 

    @Override 
    public boolean supportsParameter(MethodParameter methodParameter) { 
     return methodParameter.getParameterType().equals(ProjectVersion.class); 
    } 

    @Override 
    public Object resolveArgument(MethodParameter methodParameter, 
        ModelAndViewContainer modelAndViewContainer, 
        NativeWebRequest nativeWebRequest, 
        WebDataBinderFactory webDataBinderFactory) throws Exception { 

     return ProjectVersion.fromString(nativeWebRequest.getParameter("version")); 
    } 
} 

Wiosna-boot klasa ApplicationLauncher:

public class MyProjectApplicationLauncher extends WebMvcConfigurerAdapter { 

    @Override 
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> 
              argumentResolvers) { 
     //add the new resolver 
     argumentResolvers.add(new MyMethodArgumentResolver()); 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(MyProjectApplicationLauncher.class, args); 
    } 
} 

ProjectVersion klasa:

public enum ProjectVersion { 

    //add your existing code 

    //Add fromString method to convert string to enum 
    public static ProjectVersion fromString(String input) { 
     for (ProjectVersion projectVersion : ProjectVersion.values()) { 
      if (projectVersion.version.equals(input)) { 
      return projectVersion; 
      } 
     } 
     return null; 
    } 
} 
+0

Lepiej użyj metodyParameter.getParameterName() zamiast stałego łańcucha "version". Tak ProjectVersion.fromString (nativeWebRequest.getParameter (methodParameter.getParameterName())); – digz6666