Spring Boot 一小坑浪费一下午,虽然解决了但还是不知道原因

2019-03-28 17:06:34 +08:00
 anzu

代码并不复杂,写完 Controller 的一点基本代码后,想给传入参数做个验证,于是用了框架提供的 validation,然后噩梦开始了!

要给 @ RequestParam 的参数做验证,则需要在 controller 上注解 @ Validated,而一旦加上此注解,controller 内用 @ Autowired 注解的 service 则无法被注入,其值为 null。

// 如果删除下面这行,则 Autowired 正常
@Validated
@RestController
@RequestMapping("/test")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/hello")
    private String sayHello(
        @RequestParam @Length(min = 5) String username,
        @RequestParam @Range(min = 1, max = 100) Integer age
    ) {
        // 如果保留 Validated,则 userService == null,下面这行报错
        return userService.getHello(username, age);
    }
}

这种诡异的现象一度让我怀疑 @ Validated 与 @ Autowired 有冲突,然而搜索了很多网页都未找到有人遇到类似的问题。

更让人崩溃的是这些注解仿佛魔法一般,所有教程都告诉你,只要加上这个小东西就能轻松方便地完成功能了哦,但具体是什么原理一两句话说不清楚。

于是代码很难调试,不如说我根本无从下手,调试第一步——断点该设置在哪里呢?毫无头绪。

折腾过程略,我直接说解决方法吧:删除方法的 private 修饰,只要方法不为 private 即可。为什么?我也不太清楚,猜测可能 @ Validated 用了 Spring AOP,导致 private 方法无法被代理。希望知道确切原因的好心人能讲解一下,谢谢。

4801 次点击
所在节点    Java
26 条回复
zhazi
2019-03-29 11:12:40 +08:00
访问修饰符不提供安全性
zhazi
2019-03-29 11:14:06 +08:00
@charles2java 请教一下,哪个方法是对外的
hmellochan
2019-03-29 11:53:53 +08:00
controller 就是用来给外部访问的,还 private,另外 private 并不具有安全性,反射可解。
Seney
2019-03-29 12:29:45 +08:00
可以用 aop 拦截请求做校验 这样解耦 又不是侵入式的
thinkmore
2019-04-01 14:51:22 +08:00
@Infernalzero 在理,表示赞同
imcoming
2019-04-02 10:23:00 +08:00
没有用的代码为什么要写出来,写出来还加上 private 保证不被访问,不是脱了裤子放屁么

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/549604

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX