Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 男人都懂的www网站免费观看,亚洲午夜在线观看,在线观看91精品国产入口

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Android中的Handler, MessageQ

          Android中的Handler, MessageQueu, Message, Looper

          . ThreadLocal

          在研究Handler的機(jī)制之前我們想明確一個(gè)知識(shí)點(diǎn),ThreadLocal. ThreadLocal字面意思是線程本地變量,他保存的是一個(gè)變量的副本,并且只對(duì)當(dāng)前線程可見。我們做個(gè)例子:

          結(jié)果如下:

          可以看到第一個(gè)和第二個(gè)打印的日志是一樣的,也可能你覺得這個(gè)不能說明啥,一會(huì)我們看看源碼也許你就明白了。

          OK那我們看看他的源碼:

          在set值得時(shí)候,拿到當(dāng)前的線程,并拿到一個(gè)map,就這個(gè)值存放到map中。這個(gè)TheaLocalMap是什么呢?

          就一句話,還是從當(dāng)前的線程里面去拿的,繼續(xù)看下threadLocals:

          那么這個(gè)ThreadLocalMap 是一個(gè)什么東西呢,繼續(xù)往下看:

          可以看到這個(gè)ThreadLocalMap中有一個(gè)存儲(chǔ)結(jié)構(gòu)用來存儲(chǔ)鍵值對(duì),這個(gè)value其實(shí)就是我們set進(jìn)去的變量,繼續(xù)看下set方法:

          這個(gè)方法也不復(fù)雜,就是看看當(dāng)前的數(shù)組table中是不是已經(jīng)存過了,如果已經(jīng)存過了那么久覆蓋掉之前的Value,沒有的話就創(chuàng)建一個(gè)Entry放到數(shù)組中。所以同一個(gè)ThreadLocal在一個(gè)線程中只能存放一個(gè)值,不然會(huì)被覆蓋掉。

          當(dāng)然拿到當(dāng)前的值時(shí)候也不難,明白了這個(gè)get方法也就很簡單了。

          總結(jié)下 ThreadLocal的作用 當(dāng)前線程是綁定一個(gè)變量,只能當(dāng)前線程訪問,別的線程訪問不了也修改不了他的值。在多線程的環(huán)境中, 當(dāng)多個(gè)線程需要對(duì)某一個(gè)變量進(jìn)行頻繁的操作,但又不需要同步的時(shí)候,可以用ThreadLocal,因?yàn)樗鎯?chǔ)在當(dāng)前的線程中的,效率恨到,其實(shí)就是空間換時(shí)間。

          2. Handler Looper, MessageQueue, Message

          Handler Looper MessageQueue Message他們之間關(guān)系其實(shí)不難理解,我們new一個(gè)Handler并實(shí)現(xiàn)里面的handMessage方法,參數(shù)是一個(gè)message, 然后用Handler發(fā)送message,發(fā)送的message到了MessageQuueue這個(gè)隊(duì)列里面,Looper維持一個(gè)死循環(huán),一直從MessageQueue里面取Message,之后調(diào)用相應(yīng)的Handler里面的handMessage方法,這樣就完成了一個(gè)循環(huán)。 說起來你不難,但是要理解里面的機(jī)制,還需要看源碼:

          首先一個(gè)應(yīng)用在啟動(dòng)的時(shí)候,系統(tǒng)會(huì)調(diào)用ActivityThread.java中的main方法,在main方法里面會(huì)去初始化Looper。

          可以看到調(diào)用了Looper.prepareMainLooper();這個(gè)方法其實(shí)就是初始化了一個(gè)Looper,這個(gè)Looper是給主線程調(diào)用,接著下面調(diào)用了Looper.loop() 這個(gè)方法是開啟一個(gè)死循環(huán),一會(huì)再看,先看下Looper.prepareMainLooper()

          在上面的源碼prepare中new了一個(gè)Looper并把它放到了ThreadLocal中,上面我們已經(jīng)說了,ThreadLocal存儲(chǔ)的變量和線程綁定在一起,那么當(dāng)前的線程其實(shí)是主線程。 sMainLooper 這變量其實(shí)就是我們常用的Looper.getMainLooper().

          那么MessageQueue是什么時(shí)候創(chuàng)建的,其實(shí)就是new Looper的時(shí)候創(chuàng)建的。

          我們平常用Handler的時(shí)候都是new Handler 如下:

          那么Handler發(fā)送的的message是怎么到隊(duì)列里面,并且之后是怎么回調(diào)的,繼續(xù)看源碼:

          所有的send方法都會(huì)掉到上面這個(gè)方法里面來,然后插進(jìn)隊(duì)列:

          這個(gè)時(shí)候要注意上面的那個(gè)msg.target=this;這一句,可以看到message將會(huì)綁定當(dāng)前發(fā)送的Handler,這也就為以后出來message埋下了伏筆,其實(shí)說白了就是拿到這個(gè)target指向的Handler來調(diào)用handmessage方法處理message。

          那你有沒有注意到那個(gè)mQueue 是從哪里冒出來的?

          其實(shí)就是在new Handler的時(shí)候初始化的,可以看到上面Looper.myLooper();這句話,如果你有心的話其實(shí)上面已經(jīng)有這個(gè)方法的實(shí)現(xiàn)了:

          其實(shí)就拿的當(dāng)前線程里面的Looper,因?yàn)檫@個(gè)是在主線程里面的new的所以其實(shí)就是拿到ActivityThread里面初始化的Looper。

          既然已經(jīng)拿到messageQueue并且將message放到隊(duì)列里面的那么接下來是怎么出隊(duì)列進(jìn)行處理的呢,那就是我們的一開始就說的Looper.loop()了:

          看上面的代碼,我刪除了一些東西,最主要的是就拿到messageQueue,并有一個(gè)死循環(huán),不斷的從messageQueue里面拿去message,接著調(diào)用msg.target.dispatchMessage(msg); 在直接發(fā)送message的時(shí)候,我們看過這個(gè)target其實(shí)就是綁定的當(dāng)前的Handler,在dispatchMessage這個(gè)方法中就會(huì)去調(diào)用handMessage這個(gè)方法,到這里,整個(gè)流程就走完了。

          關(guān)于死循環(huán)的問題,可以看看https://www.zhihu.com/question/34652589/answer/90344494 可以看看這個(gè)鏈接,牽扯到了Linux系統(tǒng)管道的問題了。

          通過上面的分析我們也就知道了在主線程中可以newHandler 而在子線程中new Hander 必須自己手動(dòng)調(diào)用Looper的原因了,因?yàn)橹骶€程已經(jīng)幫我實(shí)現(xiàn)好了

          參考文章: https://www.cnblogs.com/alex-mh/p/6761233.html; https://www.cnblogs.com/alex-mh/p/6761233.html


          截器Interceptor,是SpringMVC中的核心內(nèi)容,利用spring的AOP(Aspect Oriented Programming, 面向切面編程)特性,可以很方便的對(duì)用戶的業(yè)務(wù)代碼進(jìn)行橫向抽取,根據(jù)具體業(yè)務(wù)需求對(duì)應(yīng)用功能進(jìn)行增強(qiáng)。
          在SpringBoot中使用Interceptor,同時(shí)采用全注解開發(fā),涉及到以下接口和類:

          1. HandlerInterceptor:處理器攔截器,handler就是處理器,在springboot web開發(fā)中,由控制器來處理web請(qǐng)求,因此handler具體指控制器
          2. 使用全注解開發(fā),通過@Configuration注解,讓一個(gè)java對(duì)象主任到IOC容器,并作為配置對(duì)象,這里的JavaConfig類相當(dāng)于一個(gè)xml配置文件;
          3. 在以前的xml配置中
            (1)通過引入一些標(biāo)簽進(jìn)行配置,在JavaConfig中,通過繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口來實(shí)現(xiàn)配置,這里所繼承的類、所實(shí)現(xiàn)的接口就相當(dāng)于引入的標(biāo)簽;
            (3)通過設(shè)置所引入標(biāo)簽的屬性和值,可以實(shí)現(xiàn)個(gè)性化配置,在JavaConfig中通過覆蓋類或者接口的方法來實(shí)現(xiàn)個(gè)性化配置。

          下面通過一個(gè)案例來實(shí)現(xiàn)自定義攔截器
          攔截/user/開頭的請(qǐng)求,不攔截/usr/login請(qǐng)求

          1. 定義攔截器

          1234567891011121314package cn.eis220.web;
          
          import org.springframework.web.servlet.HandlerInterceptor;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          public class LoginInterceptor implements HandlerInterceptor {
              @Override
              public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                  System.out.println("執(zhí)行了logininterceptor的preHandle方法");
                  return true;
              }
          }
          

          2. 使用JavaConfig注冊(cè)攔截器

          java配置類相當(dāng)于xml配置文件
          xml中通過引入interceptor標(biāo)簽來進(jìn)行配置,java配置類通過實(shí)現(xiàn)WebMvcController進(jìn)行配置;
          xml中通過修改標(biāo)簽的屬性和值來個(gè)性化配置,java配置類通過實(shí)現(xiàn)WebMvcController的方法進(jìn)行個(gè)性化配置

          123456789101112131415161718package cn.eis220.config;
          
          import cn.eis220.web.LoginInterceptor;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
          import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
          
          @Configuration
          public class MyAppCofnig implements WebMvcConfigurer {
              @Override
              public void addInterceptors(InterceptorRegistry registry) {
                  LoginInterceptor loginInterceptor=new LoginInterceptor();
          
                  String[] path={"/user/**"};
                  String[] excludePath={"/user/login"};
          	registry.addInterceptor(loginInterceptor).addPathPatterns(path).excludePathPatterns(excludePath);
              }
          }
          

          3. 定義控制器,測試攔截器

          123456789101112131415161718192021package cn.eis220.controller;
          
          import org.springframework.stereotype.Controller;
          import org.springframework.web.bind.annotation.RequestBody;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.ResponseBody;
          
          @Controller
          public class BootController {
              @RequestMapping("/user/account")
              @ResponseBody
              public String userAccount(){
                  return "/user/account";
              }
          
              @RequestMapping("/user/login")
              @ResponseBody
              public String userLogin(){
                  return "/user/login";
              }
          }
          

          4. 總結(jié)

          步驟:

          1. 如何定義自己的攔截器:
            實(shí)現(xiàn)HandlerInterceptor接口的方法,來自定義攔截器
          2. 如何注冊(cè)攔截器:
            JavaConfig配置類實(shí)現(xiàn)WebMvcConfigurer接口的addInterceptor方法來注冊(cè)攔截器

          本文作者:流云的博客

          本文鏈接:https://www.cnblogs.com/arminker/p/15806725.html

          時(shí)開發(fā)過程中,無可避免我們需要處理各類異常,所以這里我們?cè)诠材K中自定義統(tǒng)一異常,Spring Boot 提供 @RestControllerAdvice 注解統(tǒng)一異常處理,我們?cè)贕itEgg_Platform中新建gitegg-platform-boot子工程,此工程主要用于Spring Boot相關(guān)功能的自定義及擴(kuò)展。

          1、修改gitegg-platform-boot的pom.xml,添加spring-boot-starter-web和swagger依賴,設(shè)置optional為true,讓這個(gè)包在項(xiàng)目之間依賴不傳遞。

          <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-starter-web</artifactId>
                 <optional>true</optional>
          </dependency>
          <dependency>
                 <groupId>com.gitegg.platform</groupId>
                 <artifactId>gitegg-platform-swagger</artifactId>
                 <optional>true</optional>
          </dependency>

          2、自定義通用響應(yīng)消息類,Result和PageResult,一個(gè)是普通響應(yīng)消息,一個(gè)是分頁響應(yīng)消息。

          Result類:

          package com.gitegg.platform.boot.common.base;
          import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
          import io.swagger.annotations.ApiModel;
          import io.swagger.annotations.ApiModelProperty;
          import lombok.*;
          /**
           * @ClassName: Result
           * @Description: 自定義通用響應(yīng)類
           * @author GitEgg
           * @date 2020年09月19日 下午9:24:50
           */
          @ApiModel(description="通用響應(yīng)類")
          @Getter
          @ToString
          public class Result<T> {
              @ApiModelProperty(value="是否成功", required=true)
              private boolean success;
              
              @ApiModelProperty(value="響應(yīng)代碼", required=true)
              private int code;
              @ApiModelProperty(value="提示信息", required=true)
              private String msg;
              @ApiModelProperty(value="響應(yīng)數(shù)據(jù)")
              private T data;
              
              /**
               * 
               * @param code
               * @param data
               * @param msg
               */
              private Result(int code, T data, String msg) {
                  this.success=ResultCodeEnum.SUCCESS.code==code;
                  this.code=code;
                  this.msg=msg;
                  this.data=data;
              }
              /**
               * 
               * @param resultCodeEnum
               */
              private Result(ResultCodeEnum resultCodeEnum ) {
                  this(resultCodeEnum.code, null, resultCodeEnum.msg);
              }
              /**
               * 
               * @param resultCodeEnum
               * @param msg
               */
              private Result(ResultCodeEnum resultCodeEnum , String msg) {
                  this(resultCodeEnum, null, msg);
              }
              /**
               * 
               * @param resultCodeEnum
               * @param data
               */
              private Result(ResultCodeEnum resultCodeEnum , T data) {
                  this(resultCodeEnum, data, resultCodeEnum.msg);
              }
              /**
               * 
               * @param resultCodeEnum
               * @param data
               * @param msg
               */
              private Result(ResultCodeEnum resultCodeEnum , T data, String msg) {
                  this(resultCodeEnum.code, data, msg);
              }
              /**
               * 
               *
               * @param data 數(shù)據(jù)
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @
               */
              public static <T> Result<T> data(T data) {
                  return data(data, ResultCodeEnum.SUCCESS.msg);
              }
              /**
               * 
               *
               * @param data 數(shù)據(jù)
               * @param msg  消息
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @
               */
              public static <T> Result<T> data(T data, String msg) {
                  return data(ResultCodeEnum.SUCCESS.code, data, msg);
              }
              /**
               * 
               *
               * @param code 狀態(tài)碼
               * @param data 數(shù)據(jù)
               * @param msg  消息
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @
               */
              public static <T> Result<T> data(int code, T data, String msg) {
                  return new Result<>(code, data, msg);
              }
              /**
               * 返回Result
               *
               * @param 
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> success() {
                  return new Result<>(ResultCodeEnum.SUCCESS);
              }
              
              /**
               * 返回Result
               *
               * @param msg 消息
               * @param <T> T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> success(String msg) {
                  return new Result<>(ResultCodeEnum.SUCCESS, msg);
              }
              /**
               * 返回Result
               *
               * @param 
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> success(ResultCodeEnum resultCodeEnum ) {
                  return new Result<>(resultCodeEnum);
              }
              /**
               * 返回Result
               *
               * @param 
               * @param msg   提示信息
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> success(ResultCodeEnum resultCodeEnum , String msg) {
                  return new Result<>(resultCodeEnum, msg);
              }
              
              /**
               * 返回Result
               *
               * @param <T> T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> error() {
                  return new Result<>(ResultCodeEnum.ERROR, ResultCodeEnum.ERROR.msg);
              }
              /**
               * 返回Result
               *
               * @param msg 消息
               * @param <T> T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> error(String msg) {
                  return new Result<>(ResultCodeEnum.ERROR, msg);
              }
              /**
               * 返回Result
               *
               * @param code 狀態(tài)碼
               * @param msg  消息
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> error(int code, String msg) {
                  return new Result<>(code, null, msg);
              }
              /**
               * 返回Result
               *
               * @param 
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> error(ResultCodeEnum resultCodeEnum ) {
                  return new Result<>(resultCodeEnum);
              }
              /**
               * 返回Result
               *
               * @param 
               * @param msg   提示信息
               * @param <T>  T 響應(yīng)數(shù)據(jù)
               * @返回Result
               */
              public static <T> Result<T> error(ResultCodeEnum resultCodeEnum , String msg) {
                  return new Result<>(resultCodeEnum, msg);
              }
              
              /**
               * 
               * @param <T>
               * @param flag
               * @return
               */
              public static <T> Result<T> result(boolean flag) {
                  return flag ? Result.success("操作成功") : Result.error("操作失敗");
              }
          }

          PageResult類:

          package com.gitegg.platform.boot.common.base;
          import java.util.List;
          import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
          import io.swagger.annotations.ApiModel;
          import io.swagger.annotations.ApiModelProperty;
          import lombok.Data;
          /**
           * @ClassName: PageResult
           * @Description: 通用分頁返回
           * @author GitEgg
           * @date
           * @param <T>
           */
          @Data
          @ApiModel("通用分頁響應(yīng)類")
          public class PageResult<T> {
              @ApiModelProperty(value="是否成功", required=true)
              private boolean success;
              @ApiModelProperty(value="響應(yīng)代碼", required=true)
              private int code;
              @ApiModelProperty(value="提示信息", required=true)
              private String msg;
              @ApiModelProperty(value="總數(shù)量", required=true)
              private long count;
              @ApiModelProperty(value="分頁數(shù)據(jù)")
              private List<T> data;
              public PageResult(long total, List<T> rows) {
                  this.count=total;
                  this.data=rows;
                  this.code=ResultCodeEnum.SUCCESS.code;
                  this.msg=ResultCodeEnum.SUCCESS.msg;
              }
          }

          3、自定義通用響應(yīng)消息枚舉類ResultCodeEnum。

          package com.gitegg.platform.boot.common.enums;
          /**
           * @ClassName: ResultCodeEnum
           * @Description: 自定義返回碼枚舉
           * @author GitEgg
           * @date 2020年09月19日 下午11:49:45
           */
          public enum ResultCodeEnum {
              /**
               * 成功
               */
              SUCCESS(200, "操作成功"),
              /**
               * 系統(tǒng)錯(cuò)誤
               */
              ERROR(500, "系統(tǒng)錯(cuò)誤"),
              /**
               * 操作失敗
               */
              FAILED(101, "操作失敗"),
              /**
               * 未登錄/登錄超時(shí)
               */
              UNAUTHORIZED(102, "登錄超時(shí)"),
              /**
               * 參數(shù)錯(cuò)誤
               */
              PARAM_ERROR(103, "參數(shù)錯(cuò)誤"),
              /**
               * 參數(shù)錯(cuò)誤-已存在
               */
              INVALID_PARAM_EXIST(104, "請(qǐng)求參數(shù)已存在"),
              /**
               * 參數(shù)錯(cuò)誤
               */
              INVALID_PARAM_EMPTY(105, "請(qǐng)求參數(shù)為空"),
              /**
               * 參數(shù)錯(cuò)誤
               */
              PARAM_TYPE_MISMATCH(106, "參數(shù)類型不匹配"),
              /**
               * 參數(shù)錯(cuò)誤
               */
              PARAM_VALID_ERROR(107, "參數(shù)校驗(yàn)失敗"),
              /**
               * 參數(shù)錯(cuò)誤
               */
              ILLEGAL_REQUEST(108, "非法請(qǐng)求"),
              /**
               * 驗(yàn)證碼錯(cuò)誤
               */
              INVALID_VCODE(204, "驗(yàn)證碼錯(cuò)誤"),
              /**
               * 用戶名或密碼錯(cuò)誤
               */
              INVALID_USERNAME_PASSWORD(205, "賬號(hào)或密碼錯(cuò)誤"),
              /**
               *
               */
              INVALID_RE_PASSWORD(206, "兩次輸入密碼不一致"),
              /**
               * 用戶名或密碼錯(cuò)誤
               */
              INVALID_OLD_PASSWORD(207, "舊密碼錯(cuò)誤"),
              /**
               * 用戶名重復(fù)
               */
              USERNAME_ALREADY_IN(208, "用戶名已存在"),
              /**
               * 用戶不存在
               */
              INVALID_USERNAME(209, "用戶名不存在"),
              /**
               * 角色不存在
               */
              INVALID_ROLE(210, "角色不存在"),
              /**
               * 角色不存在
               */
              ROLE_USED(211, "角色使用中,不可刪除"),
              /**
               * 沒有權(quán)限
               */
              NO_PERMISSION(403, "當(dāng)前用戶無該接口權(quán)限");
              public int code;
              public String msg;
              ResultCodeEnum(int code, String msg) {
                  this.code=code;
                  this.msg=msg;
              }
              public int getCode() {
                  return code;
              }
              public void setCode(int code) {
                  this.code=code;
              }
              public String getMsg() {
                  return msg;
              }
              public void setMsg(String msg) {
                  this.msg=msg;
              }
          }

          4、自定義異常類BusinessException和SystemException

          package com.gitegg.platform.boot.common.exception;
          import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
          import lombok.AllArgsConstructor;
          import lombok.Data;
          import lombok.Getter;
          import lombok.Setter;
          /**
           * @ClassName: BusinessException
           * @Description: 業(yè)務(wù)處理異常
           * @author GitEgg
           * @date
           */
          @Getter
          @Setter
          public class BusinessException extends RuntimeException {
              private int code;
              private String msg;
              public BusinessException() {
                  this.code=ResultCodeEnum.FAILED.code;
                  this.msg=ResultCodeEnum.FAILED.msg;
              }
              public BusinessException(String message) {
                  this.code=ResultCodeEnum.FAILED.code;
                  this.msg=message;
              }
              public BusinessException(int code, String msg) {
                  this.code=code;
                  this.msg=msg;
              }
              public BusinessException(Throwable cause) {
                  super(cause);
              }
              public BusinessException(String message, Throwable cause) {
                  super(message, cause);
              }
          }


          package com.gitegg.platform.boot.common.exception;
          import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
          import lombok.Getter;
          /**
           * @ClassName: SystemException
           * @Description: 系統(tǒng)處理異常
           * @author GitEgg
           * @date
           */
          @Getter
          public class SystemException extends RuntimeException {
              private int code;
              private String msg;
              public SystemException() {
                  this.code=ResultCodeEnum.ERROR.code;
                  this.msg=ResultCodeEnum.ERROR.msg;
              }
              public SystemException(String message) {
                  this.code=ResultCodeEnum.ERROR.code;
                  this.msg=message;
              }
              public SystemException(int code, String msg) {
                  this.code=code;
                  this.msg=msg;
              }
              public SystemException(Throwable cause) {
                  super(cause);
              }
              public SystemException(String message, Throwable cause) {
                  super(message, cause);
              }
          }

          5、自定義統(tǒng)一異常處理類GitEggControllerAdvice.java

          package com.gitegg.platform.boot.common.advice;
          import com.gitegg.platform.boot.common.base.Result;
          import com.gitegg.platform.boot.common.enums.ResultCodeEnum;
          import com.gitegg.platform.boot.common.exception.BusinessException;
          import com.gitegg.platform.boot.common.exception.SystemException;
          import lombok.extern.slf4j.Slf4j;
          import org.springframework.beans.factory.annotation.Value;
          import org.springframework.http.converter.HttpMessageNotReadableException;
          import org.springframework.ui.Model;
          import org.springframework.web.HttpMediaTypeNotAcceptableException;
          import org.springframework.web.HttpMediaTypeNotSupportedException;
          import org.springframework.web.HttpRequestMethodNotSupportedException;
          import org.springframework.web.bind.MethodArgumentNotValidException;
          import org.springframework.web.bind.MissingPathVariableException;
          import org.springframework.web.bind.MissingServletRequestParameterException;
          import org.springframework.web.bind.WebDataBinder;
          import org.springframework.web.bind.annotation.ExceptionHandler;
          import org.springframework.web.bind.annotation.InitBinder;
          import org.springframework.web.bind.annotation.ModelAttribute;
          import org.springframework.web.bind.annotation.RestControllerAdvice;
          import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
          import org.springframework.web.servlet.NoHandlerFoundException;
          import javax.annotation.PostConstruct;
          import javax.servlet.http.HttpServletRequest;
          import javax.validation.ConstraintViolationException;
          @Slf4j
          @RestControllerAdvice
          public class GitEggControllerAdvice {
              /**
               * 服務(wù)名
               */
              @Value("${spring.application.name}")
              private String serverName;
              /**
               * 微服務(wù)系統(tǒng)標(biāo)識(shí)
               */
              private String errorSystem;
              @PostConstruct
              public void init() {
                  this.errorSystem=new StringBuffer()
                          .append(this.serverName)
                          .append(": ").toString();
              }
              /**
               * 應(yīng)用到所有@RequestMapping注解方法,在其執(zhí)行之前初始化數(shù)據(jù)綁定器
               */
              @InitBinder
              public void initBinder(WebDataBinder binder) {
              }
              /**
               * 把值綁定到Model中,使全局@RequestMapping可以獲取到該值
               */
              @ModelAttribute
              public void addAttributes(Model model) {
              }
              /**
               * 全局異常捕捉處理
               */
              @ExceptionHandler(value={Exception.class})
              public Result handlerException(Exception exception, HttpServletRequest request) {
                  log.error("請(qǐng)求路徑uri={},系統(tǒng)內(nèi)部出現(xiàn)異常:{}", request.getRequestURI(), exception);
                  Result result=Result.error(ResultCodeEnum.ERROR, errorSystem + exception.toString());
                  return result;
              }
              /**
               * 非法請(qǐng)求異常
               */
              @ExceptionHandler(value={
                      HttpMediaTypeNotAcceptableException.class,
                      HttpMediaTypeNotSupportedException.class,
                      HttpRequestMethodNotSupportedException.class,
                      MissingServletRequestParameterException.class,
                      NoHandlerFoundException.class,
                      MissingPathVariableException.class,
                      HttpMessageNotReadableException.class
              })
              public Result handlerSpringAOPException(Exception exception) {
                  Result result=Result.error(ResultCodeEnum.ILLEGAL_REQUEST, errorSystem + exception.getMessage());
                  return result;
              }
              /**
               * 非法請(qǐng)求異常-參數(shù)類型不匹配
               */
              @ExceptionHandler(value=MethodArgumentTypeMismatchException.class)
              public Result handlerSpringAOPException(MethodArgumentTypeMismatchException exception) {
                  Result result=Result.error(ResultCodeEnum.PARAM_TYPE_MISMATCH, errorSystem + exception.getMessage());
                  return result;
              }
              /**
               * 非法請(qǐng)求-參數(shù)校驗(yàn)
               */
              @ExceptionHandler(value={MethodArgumentNotValidException.class})
              public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {
                  //獲取異常字段及對(duì)應(yīng)的異常信息
                  StringBuffer stringBuffer=new StringBuffer();
                  methodArgumentNotValidException.getBindingResult().getFieldErrors().stream()
                          .map(t -> t.getField()+"=>"+t.getDefaultMessage()+" ")
                          .forEach(e -> stringBuffer.append(e));
                  String errorMessage=stringBuffer.toString();
                  Result result=Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);
                  return result;
              }
              /**
               * 非法請(qǐng)求異常-參數(shù)校驗(yàn)
               */
              @ExceptionHandler(value={ConstraintViolationException.class})
              public Result handlerConstraintViolationException(ConstraintViolationException constraintViolationException) {
                  String errorMessage=constraintViolationException.getLocalizedMessage();
                  Result result=Result.error(ResultCodeEnum.PARAM_VALID_ERROR, errorSystem + errorMessage);
                  return result;
              }
              /**
               * 自定義業(yè)務(wù)異常-BusinessException
               */
              @ExceptionHandler(value={BusinessException.class})
              public Result handlerCustomException(BusinessException exception) {
                  String errorMessage=exception.getMsg();
                  Result result=Result.error(exception.getCode(), errorSystem + errorMessage);
                  return result;
              }
              /**
               * 自定義系統(tǒng)異常-SystemException
               */
              @ExceptionHandler(value={SystemException.class})
              public Result handlerCustomException(SystemException exception) {
                  String errorMessage=exception.getMsg();
                  Result result=Result.error(exception.getCode(), errorSystem + errorMessage);
                  return result;
              }
          }

          6、重新將GitEgg-Platform進(jìn)行install,在GitEgg-Cloud中的gitegg-service引入gitegg-platform-boot

          <?xml version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
              <parent>
                  <artifactId>GitEgg-Cloud</artifactId>
                  <groupId>com.gitegg.cloud</groupId>
                  <version>1.0-SNAPSHOT</version>
              </parent>
              <modelVersion>4.0.0</modelVersion>
              <artifactId>gitegg-service</artifactId>
              <packaging>pom</packaging>
              <modules>
                  <module>gitegg-service-base</module>
                  <module>gitegg-service-bigdata</module>
                  <module>gitegg-service-system</module>
              </modules>
              <dependencies>
                  <!-- gitegg Spring Boot自定義及擴(kuò)展 -->
                  <dependency>
                      <groupId>com.gitegg.platform</groupId>
                      <artifactId>gitegg-platform-boot</artifactId>
                  </dependency>
                  <!-- gitegg數(shù)據(jù)庫驅(qū)動(dòng)及連接池 -->
                  <dependency>
                      <groupId>com.gitegg.platform</groupId>
                      <artifactId>gitegg-platform-db</artifactId>
                  </dependency>
                  <!-- gitegg mybatis-plus -->
                  <dependency>
                      <groupId>com.gitegg.platform</groupId>
                      <artifactId>gitegg-platform-mybatis</artifactId>
                  </dependency>
                  <!-- gitegg swagger2-knife4j -->
                  <dependency>
                      <groupId>com.gitegg.platform</groupId>
                      <artifactId>gitegg-platform-swagger</artifactId>
                  </dependency>
                  <!-- spring boot web核心包 -->
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-web</artifactId>
                  </dependency>
                  <!-- spring boot 健康監(jiān)控 -->
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-actuator</artifactId>
                  </dependency>
              </dependencies>
          </project>

          7、修改SystemController.java、ISystemService.java和SystemServiceImpl.java增加異常處理的測試代碼

          SystemController.java:

          package com.gitegg.service.system.controller;
          import com.gitegg.platform.boot.common.base.Result;
          import com.gitegg.platform.boot.common.exception.BusinessException;
          import com.gitegg.service.system.service.ISystemService;
          import io.swagger.annotations.Api;
          import io.swagger.annotations.ApiOperation;
          import lombok.AllArgsConstructor;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RestController;
          @RestController
          @RequestMapping(value="system")
          @AllArgsConstructor
          @Api(tags="gitegg-system")
          public class SystemController {
              private final ISystemService systemService;
              @GetMapping(value="list")
              @ApiOperation(value="system list接口")
              public Object list() {
                  return systemService.list();
              }
              @GetMapping(value="page")
              @ApiOperation(value="system page接口")
              public Object page() {
                  return systemService.page();
              }
              @GetMapping(value="exception")
              @ApiOperation(value="自定義異常及返回測試接口")
              public Result<String> exception() {
                  return Result.data(systemService.exception());
              }
          }

          ISystemService.java:

          package com.gitegg.service.system.service;
          import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
          import com.gitegg.service.system.entity.SystemTable;
          import java.util.List;
          public interface ISystemService {
              List<SystemTable> list();
              Page<SystemTable> page();
              String exception();
          }

          SystemServiceImpl.java:

          package com.gitegg.service.system.service.impl;
          import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
          import com.gitegg.platform.boot.common.exception.BusinessException;
          import com.gitegg.service.system.entity.SystemTable;
          import com.gitegg.service.system.mapper.SystemTableMapper;
          import com.gitegg.service.system.service.ISystemService;
          import lombok.AllArgsConstructor;
          import org.springframework.stereotype.Service;
          import java.util.List;
          /**
           *
           */
          @Service
          @AllArgsConstructor
          public class SystemServiceImpl implements ISystemService {
              private final SystemTableMapper systemTableMapper;
              @Override
              public List<SystemTable> list() {
                  return systemTableMapper.list();
              }
              @Override
              public Page<SystemTable> page() {
                  Page<SystemTable> page=new Page<>(1, 10);
                  List<SystemTable> records=systemTableMapper.page(page);
                  page.setRecords(records);
                  return page;
              }
              @Override
              public String exception() {
                  throw new BusinessException("自定義異常");
          //        return "成功獲得數(shù)據(jù)";
              }
          }

          8、運(yùn)行GitEggSystemApplication,打開瀏覽器訪問:http://127.0.0.1:8001/doc.html,然后點(diǎn)擊左側(cè)的異常處理接口,使用Swagger2進(jìn)行測試,即可看到結(jié)果

          源碼在https://gitee.com/wmz1930/GitEgg 的chapter-07分支。


          主站蜘蛛池模板: 好湿好大硬得深一点动态图91精品福利一区二区 | 国产天堂在线一区二区三区| 国产一区二区精品久久岳√| 亚洲AV本道一区二区三区四区| 国产一区二区三区樱花动漫| 日韩精品无码一区二区三区四区 | 精品人妻少妇一区二区| 国产乱码精品一区二区三区香蕉| 久久se精品动漫一区二区三区| 国产高清在线精品一区小说| 日本v片免费一区二区三区 | 亚洲V无码一区二区三区四区观看 亚洲爆乳精品无码一区二区三区 亚洲爆乳无码一区二区三区 | 精品人妻系列无码一区二区三区| 日本丰满少妇一区二区三区| 国产精品一区二区久久沈樵| 国产精品视频一区二区猎奇| 亚洲高清美女一区二区三区| 无码少妇一区二区| 日本亚洲成高清一区二区三区| 成人日韩熟女高清视频一区| 中文字幕亚洲乱码熟女一区二区 | 久久精品成人一区二区三区| 在线观看国产一区二三区| 久久精品无码一区二区无码| 久久久精品人妻一区亚美研究所 | 精品一区二区三区无码视频 | 中文字幕日韩丝袜一区| 久久久久人妻精品一区蜜桃| 射精专区一区二区朝鲜| 无码国产精品一区二区免费vr | 成人精品视频一区二区三区尤物| 亚洲AV无码一区二区三区牛牛| 欧美日韩精品一区二区在线观看 | 大帝AV在线一区二区三区| 日韩一区在线视频| 夜夜爽一区二区三区精品| 熟妇人妻一区二区三区四区| 蜜桃视频一区二区三区在线观看 | 在线视频一区二区日韩国产| 精品一区二区三区3d动漫| 国产美女口爆吞精一区二区|