2017-05-19 186 views
0

是否需要進行另一輪輸入驗證,與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); 
    } 
} 

回答

0

簡稱:是的,你必須再次驗證。

從設計的角度來看,你的類提供了一個公共接口,你通常不知道誰調用了這個方法。因此,爲了確保您的班級/方法正常工作,您必須驗證輸入。

如果該類使用的上下文衆所周知,並且您「知道」驗證已完成,您可以跳過附加驗證。在這種情況下,您正在接受這樣的風險,即如果將來未在控制層中執行驗證,或者您添加其他類/用例,則調用可能失敗或產生意外結果。

+0

合理。 「Service」層將驗證錯誤傳遞給Controller層的一般方法是什麼? –

+0

在'Controller'層,我們可以利用@ControllerAdvice來處理任何異常,並直接在ResponseBody中返回一個JSON。 –

+0

如果你想保持小小的努力,只需將驗證錯誤/異常傳播給Controller。正如你已經提到過的,你可以使用'@ ControllerAdvice'來處理異常。 – andih