请求绑定不适用于Kotlin类

时间:2018-07-15 18:13:45

标签: java spring-mvc spring-boot kotlin

我有一个表单对象:

for item in dir(my_library):
     if not item.startswith('_'):
         print(item)
         nam = '.'.join(['my_library', item])
         print(inspect.getsource(eval(nam)))

我有一个简单的控制器:

add
def add(x,y):
        return x+y

substract
def substract(x,y):   return x-y

工作正常。但是,如果我像这样在Kotlin中重写UserForm,则绑定不起作用(参数public class UserFormJava { @NotNull @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") private LocalDateTime dateTime; public LocalDateTime getDateTime() { return dateTime; } // getter, setter } 为空`)

@RequestMapping("/users")
@Controller
public class UserController {
    @PostMapping("")
    public String postForm(@Valid UserForm userForm, BindingResult bindingResult) {
        System.out.println(userForm + " " + bindingResult);
        return "/users/form";
    }
}

并尝试以相同方式在Controller中将其绑定:

userForm

为什么绑定失败以及如何解决?

我创建了example Github project以便复制。

2 个答案:

答案 0 :(得分:0)

您必须在userForm参数上添加RequestBody批注以绑定到Web请求的正文。 Kotlin中的UserForm类还具有一个构造函数,该构造函数的参数无法由JSON反序列化器创建。您可以使用Kotlin数据类重写它。

@RequestMapping("/users")
@Controller
public class UserController {
    @PostMapping("")
    public String postForm(@Valid @RequestBody UserForm userForm, BindingResult bindingResult){
        System.out.println(userForm + " " + bindingResult);
        return "/users/form";
    }
}

答案 1 :(得分:0)

好的,我知道了问题所在。问题实际上出在几个地方: 1.要渲染表单,我使用了以下方法:

@GetMapping("")
public String userForm(UserForm userForm) {
    userForm.setDateTime(LocalDateTime.now());
    return "/users/form";
}

如您所见,它将当前日期时间设置为现在,并在后台使用默认的Formatter

现在,在接收表单提交方面,我指定了格式:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") var dateTime: LocalDateTime? = null

但是正确的方法是使用@field:这样的目标:

@field:DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") var dateTime: LocalDateTime? = null

最后,要解决格式不一致的问题,我刚刚为Formatter添加了自定义LocalDateTime

@SpringBootApplication
public class DemoApplication implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new Formatter<LocalDateTime>() {
            final DateTimeFormatter dtFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

            @Override
            public LocalDateTime parse(String text, Locale locale) throws ParseException {
                return LocalDateTime.from(dtFormatter.parse(text));
            }

            @Override
            public String print(LocalDateTime object, Locale locale) {
                return dtFormatter.format(object);
            }
        });
    }

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