日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

如何編寫優雅的 Controller 代碼?

來源: 責編: 時間:2024-06-24 17:13:27 159觀看
導讀作為一名 Java程序員,對 Controller肯定不陌生,它是與外部客戶端通信的入口,比如常見的 REST 操作(GET、PUT、POST、DELETE等),那么,Controller里面應該如何編寫才算優雅呢?其實,一個優雅的 Controller,里面的代碼主要包含下面

作為一名 Java程序員,對 Controller肯定不陌生,它是與外部客戶端通信的入口,比如常見的 REST 操作(GET、PUT、POST、DELETE等),那么,Controller里面應該如何編寫才算優雅呢?7r828資訊網——每日最新資訊28at.com

7r828資訊網——每日最新資訊28at.com

其實,一個優雅的 Controller,里面的代碼主要包含下面 6個部分:7r828資訊網——每日最新資訊28at.com

  • 接收 HTTP(s)請求
  • 解析請求參數
  • 驗證請求參數
  • 調用業務方法
  • 組織返回數據
  • 統一異常處理

7r828資訊網——每日最新資訊28at.com

下面一一講解這 6個部分:7r828資訊網——每日最新資訊28at.com

7r828資訊網——每日最新資訊28at.com

一、接收 HTTP(s)請求

接收 HTTP(s)請求是 Controller的入口,這里以查詢用戶信息為例進行說明,如下代碼:7r828資訊網——每日最新資訊28at.com

@RestControllerpublic class UserController {    @GetMapping("/user/{userId}")    public void getUserById(@PathVariable String userId) {        // 業務邏輯    }}

在上面的示例中,我們使用 URL/user/{id}接收用戶發出的 GET請求,然后通過getUserById方法進行真實的業務處理。通過上面的代碼,一個請求就被 Controller層成功接收了。7r828資訊網——每日最新資訊28at.com

二、解析請求參數

接收到請求后,一般需要對請求參數進行解析,如下示例代碼:7r828資訊網——每日最新資訊28at.com

@RestControllerpublic class UserController {    @PostMapping("/user/register")    public void getGradeById(@RequestBody User user) {        // 代碼邏輯    }}public class User {    private String nickname;    private Integer age;    // getters and setters and constructors}

上述示例代碼將請求的 body映射到 User對象上,因此,請求的 body體應該是:7r828資訊網——每日最新資訊28at.com

{  "nickname": "huahua",  "age": "18"}

在 SpringMVC 中,常見的參數類型及其用途如下:7r828資訊網——每日最新資訊28at.com

1.原始 HTTP請求和響應對象

直接接收原始的 HTTP請求和響應對象,HttpServletRequest 和 HttpServletResponse7r828資訊網——每日最新資訊28at.com

@RequestMapping("/test")public void example(HttpServletRequest request, HttpServletResponse response) {    // 處理請求和響應}

2.路徑變量 (@PathVariable)

用于獲取 URL 路徑中的動態部分。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/user/{id}")public String getUser(@PathVariable("id") String userId) {    // 使用 userId 進行處理    return "userDetail";}

3.請求參數 (@RequestParam)

用于獲取 URL 查詢參數或表單數據。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/search")public String search(@RequestParam("query") String query) {    // 使用 query 進行搜索    return "searchResults";}

4.請求體 (@RequestBody)

用于接收請求體中的數據,常用于處理 JSON 或 XML 格式的數據。7r828資訊網——每日最新資訊28at.com

@RequestMapping(value = "/create", method = RequestMethod.POST)public String create(@RequestBody User user) {    // 處理 user 對象    return "user";}

5.模型屬性 (@ModelAttribute)

用于綁定表單數據到模型對象。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/register")public String register(@ModelAttribute User user) {    // 處理 user 對象    return "user";}

6.會話屬性 (@SessionAttribute)

用于訪問會話中的屬性。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/profile")public String profile(@SessionAttribute("user") User user) {    // 處理會話中的 user 對象    return "profile";}

7.請求頭 (@RequestHeader)

用于訪問 HTTP 請求頭信息。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/headers")public String headers(@RequestHeader("User-Agent") String userAgent) {    // 使用 userAgent 進行處理    return "headerInfo";}

8.Cookie 值 (@CookieValue)

用于訪問 Cookie 的值。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/cookies")public String cookies(@CookieValue("sessionId") String sessionId) {    // 使用 sessionId 進行處理    return sessionId;}

9.自定義參數解析器

可以通過實現 HandlerMethodArgumentResolver接口來自定義參數解析邏輯。7r828資訊網——每日最新資訊28at.com

@RequestMapping("/custom")public String custom(CustomObject customObject) {// 使用自定義對象進行處理    return "";}

三、驗證請求參數

請求參數的驗證需要在 Controller層完成,如下代碼,對 nickname進行判空處理,參數驗證一般有 2種方式:7r828資訊網——每日最新資訊28at.com

  • 原始方式,這種方式比較靈活,如果需要對參數進行一些邏輯計算后再校驗;
  • 借助三方工具,比如 Spring validation,javax validation等,這種方式靈活度會低一些,但是更優雅;
// 原始方式校驗參數@RestControllerpublic class UserController {    @PostMapping("/user/register")    public void getGradeById(@RequestBody User user) {        // 代碼邏輯        if (StringUtils.isBlank(user.getNickname)) {            throw new Exception("Nickname is required.");        }    }}

或者使用 Spring validation驗證機制,Controller需要增加@Validated注解,User對象中增加@NotBlank注解。7r828資訊網——每日最新資訊28at.com

// 借助Spring validation方式校驗參數@RestControllerpublic class UserController {    @PostMapping("/user/register")    public void getGradeById(@Validated @RequestBody User user) {        // 代碼邏輯    }}public class User {    @NotBlank(message = "Nickname is required.")    private String nickname;    private Integer age;    // getters and setters and constructors}

四、調用業務方法

如下代碼,調用 UserService.register()進行注冊業務處理:7r828資訊網——每日最新資訊28at.com

@RestControllerpublic class UserController {    private final UserService userService;    public UserController(UserService userService) {        this.userService = userService;    }    @PostMapping("/user/register")    public void getGradeById(@Validated @RequestBody User user) {        // 調用注冊的業務方法        userService.register(user);    }}public class User {    @NotBlank(message = "Nickname is required.")    private String nickname;    private Integer age;    // getters and setters and constructors}

關于調用業務方法,這里的業務方法是寫一個大而全的方法?還是需要按業務歸類?7r828資訊網——每日最新資訊28at.com

遵守一個原則:有強關聯性的邏輯放在一個service方法內,沒有強關聯性的單令拎出來。7r828資訊網——每日最新資訊28at.com

這里以用戶注冊之后需要新人發券為例進行說明:7r828資訊網——每日最新資訊28at.com

大而全的方法:7r828資訊網——每日最新資訊28at.com

    @PostMapping("/user/register")    public void getGradeById(@Validated @RequestBody User user) {        // 調用注冊的業務方法        userService.doRegister(user);    }        public String doRegister(Uswr user){        String userId = userService.register(user);        coupon.sendCoupon(userId);        // 其他業務邏輯        return userId;    }

業務歸類:7r828資訊網——每日最新資訊28at.com

    @PostMapping("/user/register")    public void getGradeById(@Validated @RequestBody User user) {        // 調用注冊的業務方法        userService.register(user);        coupon.sendCoupon(userId);    }

五、組織返回數據

如下代碼,調用 UserService.register()進行注冊業務處理:7r828資訊網——每日最新資訊28at.com

@RestControllerpublic class UserController {    private final UserService userService;    public UserController(UserService userService) {        this.userService = userService;    }    @PostMapping("/user/register")    public UserResponse getGradeById(@Validated @RequestBody User user) {        // 調用注冊的業務方法        String userId = userService.regist(user);        return new UserResponse(userId, user.getNickname);    }}public class UserResponse {    private String userId;    private String nickname;    // getters and setters and constructors}

六、統一異常處理

比如上述過程在 userService.regist(user);出現異常時,可以做一個try-catch,然后在 Controller層封裝有業務意思的異常信息:7r828資訊網——每日最新資訊28at.com

@RestControllerpublic class UserController {    private final UserService userService;    @PostMapping("/user/register")    public UserResponse getGradeById(@Validated @RequestBody User user) {        // 調用注冊的業務方法        try {            String userId = userService.regist(user);        } catch (Exception e) {            throw new CustomException();        }        return new UserResponse(userId, user.getNickname);    }}

建議和總結

看過很多代碼,業務邏輯全部寫在 Controller層,并不能說這樣的做法是錯的,但是看起來很別扭,不優雅!因此,建議在編寫代碼時,最好能遵守一個比較好的規范,比如常見的SOLID規范。7r828資訊網——每日最新資訊28at.com

SOLID 實際上是五個設計原則首字母的縮寫,它們分別是:7r828資訊網——每日最新資訊28at.com

  • 單一職責原則(Single responsibility principle, SRP)
  • 開放封閉原則(Open–closed principle, OCP)
  • Liskov 替換原則(Liskov substitution principle, LSP)
  • 接口隔離原則(Interface segregation principle, ISP)
  • 依賴倒置原則(Dependency inversion principle, DIP)

另外,建議我們技術人員平時多去閱讀一些優秀開源框架,學習他們的設計思想,代碼規范,相信我:養成一個良好的編碼規范,絕對受益頗多!7r828資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-96045-0.html如何編寫優雅的 Controller 代碼?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 美國兩名 05 后高中生聯手打造 API 初創,已獲 50 萬美元融資

下一篇: Python 處理 CSV 文件的 12 個高效技巧

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 鱼台县| 伊宁县| 徐汇区| 郁南县| 瓦房店市| 上林县| 博白县| 陈巴尔虎旗| 桓台县| 那曲县| 甘孜| 济源市| 汶上县| 诸城市| 五大连池市| 大埔县| 陇南市| 津市市| 安图县| 仁化县| 静海县| 津南区| 于都县| 南雄市| 玉环县| 衡阳市| 福鼎市| 神农架林区| 青海省| 灵川县| 五寨县| 蒲城县| 双桥区| 麻阳| 曲阳县| 吉隆县| 朝阳县| 平远县| 富民县| 毕节市| 郎溪县|