spring 4枚举作为控制器参数

时间:2016-01-27 08:36:52

标签: java spring enums

稍后修改

我描述的案例运作正常。当我在控制器的方法上有这样的东西时会出现问题:

@RestController 
public class MyController {
  @RequestMapping(...)
  public void myMethod(@RequestBody MyForm myform) { ... }
}

public class MyForm {
  private X x;
  //setters and getters
}

原因

  

给定RequestBody,Spring将使用HttpMessageConverter将您的请求主体反序列化为您给定类型的实例。在这种情况下,它将使用MappingJackson2HttpMessageConverter作为JSON。此转换器根本不涉及PropertyEditorSupport。

任何替代方案?在这种情况下,我需要使用@RequestBody或找到将X放入myform的方法。

我想将一个枚举作为参数放在REST控制器的方法中。

这是我到目前为止所做的。

枚举:

public enum X {
  A("A"),B("B"),C("C");
  ... methods and constructors ...
}

控制器:

@RestController 
public class MyController {
  @RequestMapping(...)
  public void myMethod(@PathVariable("x") X x) { ... }
}

配置:

@ControllerAdvice
public class GlobalControllerConfig {
    @InitBinder
    public void registerCustomEditors(WebDataBinder binder, WebRequest request) {
      binder.registerCustomEditor(X.class, new XPropertyEditor());
    }
}

属性编辑器:

public class XPropertyEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) {
        try {
            setValue(X.findByName(text));
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Custom binding failed. Input type: String. Expected type of value to be set: X", e);
        }
    }

    @Override
    public String getAsText() {
        return ((X)getValue()).getName();
    }
}

我在@ControllerAdvice中放了一个断点,每次向我的任何控制器发出请求时,它都会通过该绑定。这让我觉得绑定是正确的。

当我向我的方法发送请求时,我得到了这个,我不明白为什么:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not construct instance of ...X from String value 'A': value not one of declared Enum instance names: [A, B, C]

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

尝试将@RequestVariable更改为@RequestParameter。

我改变 setAsText 方法行,如下所示:

@Override
public void setAsText(String text) {
    try {
        String upperText = text.toUpperCase(); 
        X xResult = X.valueOf(upperText);
        setValue(xResult);
    } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException("Custom binding failed. Input type: String. Expected type of value to be set: X", e);
    }
}