最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談springmvc 通過異常增強(qiáng)返回給客戶端統(tǒng)一格式

 更新時(shí)間:2020年09月26日 14:34:54   作者:nosqlcoco  
這篇文章主要介紹了淺談springmvc 通過異常增強(qiáng)返回給客戶端統(tǒng)一格式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

在springmvc開發(fā)中,我們經(jīng)常遇到這樣的問題;邏輯正常執(zhí)行時(shí)返回客戶端指定格式的數(shù)據(jù),比如json,但是遇NullPointerException空指針異常,NoSuchMethodException調(diào)用的方法不存在異常,返回給客戶端的是服務(wù)端異常堆棧信息,導(dǎo)致客戶端不能正常解析數(shù)據(jù);這明顯不是我們想要的。

幸好從spring3.2提供的新注解@ControllerAdvice,從名字上可以看出大體意思是控制器增強(qiáng)。原理是使用AOP對(duì)Controller控制器進(jìn)行增強(qiáng)(前置增強(qiáng)、后置增強(qiáng)、環(huán)繞增強(qiáng),AOP原理請(qǐng)自行查閱);那么我沒可以自行對(duì)控制器的方法進(jìn)行調(diào)用前(前置增強(qiáng))和調(diào)用后(后置增強(qiáng))的處理。

spring提供了@ExceptionHandler異常增強(qiáng)注解。程序如果在執(zhí)行控制器方法前或執(zhí)行時(shí)拋出異常,會(huì)被@ExceptionHandler注解了的方法處理。

配置applicationContext-mvc.xml:

<!-- 使用Annotation自動(dòng)注冊(cè)Bean,掃描@Controller和@ControllerAdvice-->
<context:component-scan base-package="com.drskj.apiservice" use-default-filters="false">
  <!-- base-package 如果多個(gè),用“,”分隔 -->
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
  <!--控制器增強(qiáng),使一個(gè)Contoller成為全局的異常處理類,類中用@ExceptionHandler方法注解的方法可以處理所有Controller發(fā)生的異常-->
  <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>

全局異常處理類:

package com.drskj.apiservice.handler;
import java.io.IOException;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.drskj.apiservice.common.utils.ReturnFormat;
/**
 * 異常增強(qiáng),以JSON的形式返回給客服端 * 異常增強(qiáng)類型:NullPointerException,RunTimeException,ClassCastException,         NoSuchMethodException,IOException,IndexOutOfBoundsException         以及springmvc自定義異常等,如下:SpringMVC自定義異常對(duì)應(yīng)的status code 
      Exception            HTTP Status Code 
ConversionNotSupportedException     500 (Internal Server Error)
HttpMessageNotWritableException     500 (Internal Server Error)
HttpMediaTypeNotSupportedException   415 (Unsupported Media Type)
HttpMediaTypeNotAcceptableException   406 (Not Acceptable)
HttpRequestMethodNotSupportedException 405 (Method Not Allowed)
NoSuchRequestHandlingMethodException  404 (Not Found) 
TypeMismatchException          400 (Bad Request)
HttpMessageNotReadableException     400 (Bad Request)
MissingServletRequestParameterException 400 (Bad Request)
 *
 */
@ControllerAdvice
public class RestExceptionHandler{
  //運(yùn)行時(shí)異常
  @ExceptionHandler(RuntimeException.class) 
  @ResponseBody 
  public String runtimeExceptionHandler(RuntimeException runtimeException) { 
    return ReturnFormat.retParam(1000, null);
  } 
  //空指針異常
  @ExceptionHandler(NullPointerException.class) 
  @ResponseBody 
  public String nullPointerExceptionHandler(NullPointerException ex) { 
    ex.printStackTrace();
    return ReturnFormat.retParam(1001, null);
  }  
  //類型轉(zhuǎn)換異常
  @ExceptionHandler(ClassCastException.class) 
  @ResponseBody 
  public String classCastExceptionHandler(ClassCastException ex) { 
    ex.printStackTrace();
    return ReturnFormat.retParam(1002, null); 
  } 
  //IO異常
  @ExceptionHandler(IOException.class) 
  @ResponseBody 
  public String iOExceptionHandler(IOException ex) { 
    ex.printStackTrace();
    return ReturnFormat.retParam(1003, null); 
  } 
  //未知方法異常
  @ExceptionHandler(NoSuchMethodException.class) 
  @ResponseBody 
  public String noSuchMethodExceptionHandler(NoSuchMethodException ex) { 
    ex.printStackTrace();
    return ReturnFormat.retParam(1004, null);
  } 
  //數(shù)組越界異常
  @ExceptionHandler(IndexOutOfBoundsException.class) 
  @ResponseBody 
  public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) { 
    ex.printStackTrace();
    return ReturnFormat.retParam(1005, null);
  }
  //400錯(cuò)誤
  @ExceptionHandler({HttpMessageNotReadableException.class})
  @ResponseBody
  public String requestNotReadable(HttpMessageNotReadableException ex){
    System.out.println("400..requestNotReadable");
    ex.printStackTrace();
    return ReturnFormat.retParam(400, null);
  }
  //400錯(cuò)誤
  @ExceptionHandler({TypeMismatchException.class})
  @ResponseBody
  public String requestTypeMismatch(TypeMismatchException ex){
    System.out.println("400..TypeMismatchException");
    ex.printStackTrace();
    return ReturnFormat.retParam(400, null);
  }
  //400錯(cuò)誤
  @ExceptionHandler({MissingServletRequestParameterException.class})
  @ResponseBody
  public String requestMissingServletRequest(MissingServletRequestParameterException ex){
    System.out.println("400..MissingServletRequest");
    ex.printStackTrace();
    return ReturnFormat.retParam(400, null);
  }
  //405錯(cuò)誤
  @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
  @ResponseBody
  public String request405(){
    System.out.println("405...");
    return ReturnFormat.retParam(405, null);
  }
  //406錯(cuò)誤
  @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
  @ResponseBody
  public String request406(){
    System.out.println("404...");
    return ReturnFormat.retParam(406, null);
  }
  //500錯(cuò)誤
  @ExceptionHandler({ConversionNotSupportedException.class,HttpMessageNotWritableException.class})
  @ResponseBody
  public String server500(RuntimeException runtimeException){
    System.out.println("500...");
    return ReturnFormat.retParam(406, null);
  }
}

以上包括了常見的服務(wù)端異常類型,@ResponseBody表示以json格式返回客戶端數(shù)據(jù)。我們也可以自定義異常類(這里我把它叫做MyException)并且繼承RunTimeException,并且在全局異常處理類新增一個(gè)方法來處理異常,使用@ExceptionHandler(MyException.class)注解在方法上實(shí)現(xiàn)自定義異常增強(qiáng)。

格式化response數(shù)據(jù)類ReturnFormat:

package com.drskj.apiservice.common.utils;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;import com.google.common.collect.Maps;
//格式化返回客戶端數(shù)據(jù)格式(json)
public class ReturnFormat {
  private static Map<String,String>messageMap = Maps.newHashMap();
  //初始化狀態(tài)碼與文字說明
  static {
    messageMap.put("0", "");
    messageMap.put("400", "Bad Request!");
    messageMap.put("401", "NotAuthorization");
    messageMap.put("405", "Method Not Allowed");
    messageMap.put("406", "Not Acceptable");
    messageMap.put("500", "Internal Server Error");
    messageMap.put("1000", "[服務(wù)器]運(yùn)行時(shí)異常");
    messageMap.put("1001", "[服務(wù)器]空值異常");
    messageMap.put("1002", "[服務(wù)器]數(shù)據(jù)類型轉(zhuǎn)換異常");
    messageMap.put("1003", "[服務(wù)器]IO異常");
    messageMap.put("1004", "[服務(wù)器]未知方法異常");
    messageMap.put("1005", "[服務(wù)器]數(shù)組越界異常");
    messageMap.put("1006", "[服務(wù)器]網(wǎng)絡(luò)異常");
    messageMap.put("1010", "用戶未注冊(cè)");
    messageMap.put("1011", "用戶已注冊(cè)");
    messageMap.put("1012", "用戶名或密碼錯(cuò)誤");
    messageMap.put("1013", "用戶帳號(hào)凍結(jié)");
    messageMap.put("1014", "用戶信息編輯失敗");
    messageMap.put("1015", "用戶信息失效,請(qǐng)重新獲取");
    messageMap.put("1020", "驗(yàn)證碼發(fā)送失敗");
    messageMap.put("1021", "驗(yàn)證碼失效");
    messageMap.put("1022", "驗(yàn)證碼錯(cuò)誤");
    messageMap.put("1023", "驗(yàn)證碼不可用");
    messageMap.put("1029", "短信平臺(tái)異常");
    messageMap.put("1030", "周邊無店鋪");
    messageMap.put("1031", "店鋪添加失敗");
    messageMap.put("1032", "編輯店鋪信息失敗");
    messageMap.put("1033", "每個(gè)用戶只能添加一個(gè)商鋪");
    messageMap.put("1034", "店鋪不存在");
    messageMap.put("1040", "無瀏覽商品");
    messageMap.put("1041", "添加失敗,商品種類超出上限");
    messageMap.put("1042", "商品不存在");
    messageMap.put("1043", "商品刪除失敗");
    messageMap.put("2010", "缺少參數(shù)或值為空");
    
    messageMap.put("2029", "參數(shù)不合法");
    messageMap.put("2020", "無效的Token");
    messageMap.put("2021", "無操作權(quán)限");
    messageMap.put("2022", "RSA解密失敗,密文數(shù)據(jù)已損壞");
    messageMap.put("2023", "請(qǐng)重新登錄");
  }
  public static String retParam(int status,Object data) {
    OutputJson json = new OutputJson(status, messageMap.get(String.valueOf(status)), data);
    return json.toString();
  }
}

返回格式實(shí)體類OutPutJson;這里用到了知名的fastjson將對(duì)象轉(zhuǎn)json:

package com.drskj.apiservice.common.utils;
import java.io.Serializable;
import com.alibaba.fastjson.JSON;
public class OutputJson implements Serializable{
  /**
   * 返回客戶端統(tǒng)一格式,包括狀態(tài)碼,提示信息,以及業(yè)務(wù)數(shù)據(jù)
   */
  private static final long serialVersionUID = 1L;
  //狀態(tài)碼
  private int status;
  //必要的提示信息
  private String message;
  //業(yè)務(wù)數(shù)據(jù)
  private Object data;
  public OutputJson(int status,String message,Object data){
    this.status = status;
    this.message = message;
    this.data = data;
  }
  public int getStatus() {
    return status;
  }
  public void setStatus(int status) {
    this.status = status;
  }
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }
  public Object getData() {
    return data;
  }
  public void setData(Object data) {
    this.data = data;
  }
  public String toString(){
    if(null == this.data){
      this.setData(new Object());
    }
    return JSON.toJSONString(this);
  }
}

實(shí)例:CodeController繼承自BaseController,有一個(gè)sendMessage方法調(diào)用Service層發(fā)送短信驗(yàn)證碼;

1.如果客戶端請(qǐng)求方式為非POST,否則拋出HttpMediaTypeNotSupportedException異常;

2.如果username、forType或userType沒傳,則拋出MissingServletRequestParameterException異常;

3.如果springmvc接收無法進(jìn)行類型轉(zhuǎn)換的字段,會(huì)報(bào)TypeMismatchException異常;

.....

大部分的請(qǐng)求異常,springmvc已經(jīng)為我們定義好了,為我們開發(fā)restful應(yīng)用提高了測(cè)試效率,方便排查問題出在哪一環(huán)節(jié)。

@RestController@RequestMapping("/api/v1/code")
public class CodeController extends BaseController {
  @Autowired
  private CodeService codeService;
  
  /**
   * 發(fā)送短信
   * @param username 用戶名
   * @param type register/backpwd
   * @return
   * status: 0 2010 2029 1011 1010 1006 1020 
   */
  @RequestMapping(value="/sendMessage",method=RequestMethod.POST,produces="application/json")
  public String sendMessage(@RequestParam(value="username",required=true)String username,
      @RequestParam(value="forType",required=true)String forType,
      @RequestParam(value="userType",required=true)String userType){
    if(null == username || "".equals(username)){
      return retContent(2010, null);
    }
    if(!"user".equals(userType) && !"merchant".equals(userType)){
      return retContent(2029, null);
    }
    if(!"register".equals(forType) && !"backpwd".equals(forType)){
      return retContent(2029, null);
    }
    return codeService.sendMessage(username, forType, userType);
  }
}
public abstract class BaseController {
  protected String retContent(int status,Object data) {
    return ReturnFormat.retParam(status, data);
  }
}

最終,不管是正常的業(yè)務(wù)邏輯還是服務(wù)端異常,都會(huì)調(diào)用ReturnFormat.retParam(int status,Object data)方法返回格式統(tǒng)一的數(shù)據(jù)。

以上這篇淺談springmvc 通過異常增強(qiáng)返回給客戶端統(tǒng)一格式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java 中的Printstream介紹_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java 中的Printstream介紹_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    PrintStream 是打印輸出流,它繼承于FilterOutputStream。接下來通過本文給大家介紹Java 中的Printstream,需要的朋友參考下吧
    2017-05-05
  • Java中new與clone操作對(duì)象的比較方法舉例

    Java中new與clone操作對(duì)象的比較方法舉例

    這篇文章主要給大家介紹了關(guān)于Java中new與clone操作對(duì)象的比較方法,在java中對(duì)象的誕生是我們開發(fā)人員new出來的,對(duì)象的使用也是我們開發(fā)人員進(jìn)行操作的,需要的朋友可以參考下
    2024-07-07
  • 通過使用Byte?Buddy便捷創(chuàng)建Java?Agent

    通過使用Byte?Buddy便捷創(chuàng)建Java?Agent

    這篇文章主要為大家介紹了如何通過使用Byte?Buddy便捷創(chuàng)建Java?Agent的使用說明,有需要的朋友可以借鑒參考下希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • java 實(shí)現(xiàn)迷宮回溯算法示例詳解

    java 實(shí)現(xiàn)迷宮回溯算法示例詳解

    這篇文章主要介紹了java 實(shí)現(xiàn)迷宮回溯算法示例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java語言實(shí)現(xiàn)掃雷游戲(2)

    Java語言實(shí)現(xiàn)掃雷游戲(2)

    這篇文章主要為大家詳細(xì)介紹了Java語言實(shí)現(xiàn)掃雷游戲第二部分代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Java中&&與?表達(dá)式結(jié)合時(shí)出現(xiàn)的坑

    Java中&&與?表達(dá)式結(jié)合時(shí)出現(xiàn)的坑

    這篇文章主要給大家介紹了關(guān)于Java中&&與?表達(dá)式結(jié)合時(shí)出現(xiàn)的坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Java實(shí)現(xiàn)Jar文件的遍歷復(fù)制與文件追加

    Java實(shí)現(xiàn)Jar文件的遍歷復(fù)制與文件追加

    這篇文章主要為大家詳細(xì)介紹了如何利用Java實(shí)現(xiàn)Jar文件的遍歷復(fù)制與文件追加功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • Spring項(xiàng)目中Ordered接口的應(yīng)用之全局過濾器(GlobalFilter)的順序控制

    Spring項(xiàng)目中Ordered接口的應(yīng)用之全局過濾器(GlobalFilter)的順序控制

    在Spring框架,尤其是Spring Cloud Gateway或Spring WebFlux項(xiàng)目中,Ordered接口扮演著重要的角色,特別是在實(shí)現(xiàn)全局過濾器(GlobalFilter)時(shí),用于控制過濾器執(zhí)行的優(yōu)先級(jí),下面將介紹如何在Spring項(xiàng)目中使用Ordered接口來管理Global Filter的執(zhí)行順序,需要的朋友可以參考下
    2024-06-06
  • Java多線程模式之Balking模式詳解

    Java多線程模式之Balking模式詳解

    這篇文章主要介紹了Java多線程模式之Balking模式,結(jié)合實(shí)例形式較為詳細(xì)的分析了Balking模式的原理、用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-06-06
  • SpringMVC+Mybatis實(shí)現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例

    SpringMVC+Mybatis實(shí)現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例

    本篇文章主要介紹了SpringMVC+Mybatis實(shí)現(xiàn)的Mysql分頁數(shù)據(jù)查詢的示例,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08

最新評(píng)論

宝应县| 甘孜县| 蒲江县| 云和县| 黄平县| 石嘴山市| 石城县| 鹤庆县| 博白县| 海丰县| 鄯善县| 西乡县| 延津县| 泸水县| 清水河县| 黄平县| 大渡口区| 巫山县| 桂平市| 柳林县| 集贤县| 当阳市| 红原县| 扶绥县| 浪卡子县| 民县| 怀化市| 沙坪坝区| 明溪县| 开原市| 南宁市| 恭城| 姜堰市| 吴桥县| 巴楚县| 三门县| 易门县| 沽源县| 塔河县| 都匀市| 宁海县|