【问题标题】:Validation at both Service and Controller Layer?在服务层和控制器层进行验证?
【发布时间】:2017-10-19 01:08:29
【问题描述】:

是否需要在service层进行另一轮输入验证,非业务逻辑相关?

服务层

@Service
@Transactional
@Validated
public class AppServiceImpl implements AppService {

    public App createApp(@Valid App app) { // is there a need to do @Valid here?
        return appRepository.save(app);
    }
}

控制器层

@RestController
@RequestMapping("/api")
public class AppResource {
    private final AppRepository appRepository;

    private final AppServiceImpl appServiceImpl;

    @Autowired
    public AppResource(AppRepository appRepository, AppServiceImpl appServiceImpl) {
        this.appServiceImpl = appServiceImpl;
        this.appRepository = appRepository;
    }

    /**
     * POST  /apps : Create a new app.
     *
     * @param app the app to create
     * @return the ResponseEntity with status 201 (Created) and with body the new app, or with status 400 (Bad Request) if the app has already an ID
     * @throws URISyntaxException if the Location URI syntax is incorrect
     */
    @PostMapping("/apps")
    @Timed
    public ResponseEntity<App> createApp(@Valid @RequestBody App app) throws URISyntaxException {
        log.debug("REST request to save App : {}", app);
        if (app.getId() != null) {
            return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(ENTITY_NAME, "idexists", "A new app cannot already have an ID")).body(null);
        }
        App result = appServiceImpl.createApp(app);
        return ResponseEntity.created(new URI("/api/apps/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
            .body(result);
    }
}

【问题讨论】:

    标签: spring spring-mvc


    【解决方案1】:

    简短形式:是的,您必须再次验证。

    从设计的角度来看,您的类提供了一个公共接口,您通常不知道是谁调用了该方法。因此,为了确保您的类/方法正常工作,您必须验证输入。

    如果使用该类的上下文是众所周知的,并且您“知道”验证已完成,然后您可以跳过额外的验证。在这种情况下,您接受的风险是,如果将来未在控制层中完成验证,或者您添加其他类/用例,调用可能会失败或产生意外结果。

    【讨论】:

    • 有道理。那么Service 层将验证错误传递到Controller 层的一般方法是什么?
    • 在Controller层我们可以利用@ControllerAdvice来处理任何异常,直接在ResponseBody中返回一个JSON。
    • 如果您想减少工作量,只需将验证错误/异常传播到Controller。正如您已经提到的,您可以使用@ControllerAdvice 来处理异常。
    猜你喜欢
    • 2014-02-19
    • 2017-05-01
    • 1970-01-01
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多