2017-04-06 60 views
5

我有一個彈簧引導控制器,我的一個參數是一個枚舉。枚舉有一個字符串值。我想通過作爲參數的枚舉值和控制器給我枚舉。這可以做到嗎?彈簧引導控制器 - 枚舉參數作爲值

@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; 
    } 

} 

我希望能夠做出要求如下:

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

並在控制器獲得ProjectVersion.VERSION_1

任何想法?

+0

是,自定義序列化。看到這個,正是你的情況:http://stackoverflow.com/questions/7766791/serializing-enums-with-jackson –

+1

如果你通過'VERSION_1'它會工作,如果你通過內部價值它不會然後你會需要自己創建一個自定義轉換器。 –

回答

5

這是不可能的。您必須創建自定義轉換器,將其從String轉換爲ProjectVersion

例如首先定義從StringProjectVersion轉換器:

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); 
    } 
} 

然後將其註冊:

@Configuration 
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { 

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

如果你定義ProjectVersionConverter您可以跳過註冊有一個Spring bean。 (這段代碼沒有經過測試)。

+0

使用參數解析器是更清潔和更好的方法。 – digz6666

+0

我不同意。轉換器不應該擔心該值會作爲請求參數或路徑變量傳遞。只要使用正確的註釋,使用不可知的轉換器,它應該可以工作。 –

1

因爲需要傳遞(對於每個請求)的參數的Controller方法,所述清潔溶液是使用HandlerMethodArgumentResolver,使得 Spring容器可以動態地注入你ProjectVersion參數傳遞給控制器​​方法如下所示:

ProjectVersionArgumentResolver類:

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")); 
    } 
} 

春季啓動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類:

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

更好地使用methodParameter.getParameterName()而不是硬編碼的字符串「version」。所以ProjectVersion.fromString(nativeWebRequest.getParameter(methodParameter.getParameterName())); – digz6666