簡體   English   中英

編寫控制器的正確方法

[英]Proper way to write a controller

我想知道在前端根據服務結果在控制器中構建消息的最佳方法是什么。 我在使用rest控制器的java / spring上下文中考慮,但它也反映了MVC模型。 顯然,我在Internet上看到的示例是一種簡單的方法,可以用來簡單地了解什么是實際應用中的最佳實踐。 因此,對於這種情況,讓我們假設以下情形:

  1. 我們有一個具有單個方法doMath(int a,int b)的控制器CalculateController
  2. 我們有一個服務CalculatorService,它在doMath(int a,int b)方法中自行執行數學運算。
  3. 我們要對輸入參數執行其他驗證。 該方法稱為validateInput(int a,int b)。
  4. 我們要發送失敗的原因作為響應計算結果或特定信息。

所以現在的問題是:

  1. 作為執行控制器方法的結果,我將重新獲得一個Map對象,該對象將被解析為JSON。 可能的實體為:

    {“結果”:“ 12”}

    {“ errorCode”:“參數不正確”}

這是正確的,還是我應該針對不同的錯誤處理? 我知道我可以另外使用http錯誤代碼(例如400或406)來指示輸入參數不正確,但是我個人不希望使用http錯誤代碼來指示應用程序邏輯結果。 (我認為輸入驗證是應用邏輯)

  1. validateInput方法應放置在控制器,服務中的何處?
  2. 在validateInput方法中,我要檢查兩個簡化的條件

a)是<b,然后通知用戶消息“ a不能小於b”

b)是a * a == b,然后通知用戶消息“平方不能等於b”。

如何根據結果提供其他消息? 我可以想到兩種解決方案:

  • 返回Map,如果驗證結果為肯定,則結果為true,如果結果為否定,則結果為false,以及帶有相應消息的errorCode
  • 返回指示驗證結果的布爾值,另外對否定結果使用異常。 (額外的問題,在這種情況下應該檢查還是不檢查異常?)

    1. 對於服務方法,應該以相同的方式處理?

關於問題2和問題3,您可能需要查看Validator界面: http : //docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html

這篇文章展示了如何使用: Spring MVC:如何執行驗證?

對於問題1,您可以將BindingResult中的錯誤轉換為JSON,並在客戶端使用它對用戶執行有用的反饋。

另外,我認為,在這種情況下,您不應使用HTTP錯誤代碼,因為用戶輸入錯誤實際上不是錯誤,而是應用程序中的正常使用情況。

Spring支持自定義驗證。 有一個注釋@Valid 您可以將其添加到Controller中的參數之前。 我將在示例中展示它。 首先,創建帶有實現Validator接口的類:

@Component
public class MathValidator implements Validator {

    @Override
    public boolean supports(Class<?> aClass) {
        return MatchRequest.class.equals(aClass);
    }

    @Override
    public void validate(Object o, Errors errors) {
        MatchRequest request = (MatchRequest) o;

        if (request.getValue() == null) {
            errors.rejectValue("value", "Value cannot be empty");
        }
       //add another validation logic here.
    }
}

然后,在Controller中,您可以像這樣注入驗證器:

@Autowired
private MathValidator validator;

並在此方法中添加注釋,以顯示spring應該驗證的形式。 注釋中的名稱是控制器方法中參數的名稱。

@InitBinder("request")
private void initBinder(WebDataBinder binder) {
    binder.setValidator(routeValidator);
}

讓我們專注於控制器方法。 我們在這里用@Valid注釋了參數。 Spring將從您已經實現的類中調用validate方法。 必須具有第二個參數: Binding result

@RequestMapping(value = "/math", method = RequestMethod.POST)
        public ResponseEntity calculate(@RequestBody @Valid MatchRequest request, BindingResult result) {
            if (result.hasErrors()) {
                return new ResponseEntity(result.getAllErrors(), HttpStatus.BAD_GATEWAY);
            }

            //call service,etc.
        }  

此外,春季還有另一個有趣的工具。 它是注解@ExceptionHandler 使用此批注,您可以將從控制器或服務引發的異常映射到http請求。 在官方網站上閱讀有關此主題的更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM