springmvc请求参数异常统一处理,结合钉钉报告信息定位bug位置

参考之前一篇博客:springmvc请求参数异常统一处理

1、ExceptionHandlerController

package com.oy.controller;

import java.text.MessageFormat;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
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 org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

import com.alibaba.fastjson.JSONObject;

import com.oy.exception.ForbiddenException;
import com.oy.exception.JwebException;
import com.oy.utils.ErrCode;
import com.oy.utils.Response;
import com.oy.utils.UtilFunctions;

@ControllerAdvice
public class ExceptionHandlerController {

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public JSONObject runtimeExceptionHandler(RuntimeException ex) {
        UtilFunctions.log.error("runtimeExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        UtilFunctions.reportError("runtimeExceptionHandler: " + ex.toString(), ex);
        JSONObject response = new JSONObject();
        response.put("message", "Internal Server Error");
        return response;
    }

    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public JSONObject nullPointerExceptionHandler(NullPointerException ex) {
        UtilFunctions.log.error("nullPointerExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        UtilFunctions.reportError("runtimeExceptionHandler: " + ex.toString(), ex);
        JSONObject response = new JSONObject();
        response.put("message", "Internal Server Error");
        return response;
    }

    /*----- REQUEST ERROR -----*/
    @ExceptionHandler({ ForbiddenException.class })
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ResponseBody
    public JSONObject requestForbidden(ForbiddenException ex) {
        UtilFunctions.log.error("ForbiddenExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        JSONObject response = new JSONObject();
        response.put("message", ex.getMessage());
        return response;
    }

    @ExceptionHandler({ TypeMismatchException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public JSONObject requestTypeMismatch(TypeMismatchException ex) {
        UtilFunctions.log.error("TypeMismatchExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        JSONObject response = new JSONObject();
        // response.put("message", "Bad Request");
        // response.put("message", "Bad Request,  parameter type of " + ex.getPropertyName() + " need be " + ex.getRequiredType());

        if (Double.class.equals(ex.getRequiredType()) ||  Integer.class.equals(ex.getRequiredType())) {
            response.put("message", "Bad Request, " +  ex.getValue() + " not a number");
        } else {
            String strTemplate = "Bad Request, {0} is invalid, a type of {1} is needed";
            response.put("message", MessageFormat.format(strTemplate, ex.getValue(), ex.getRequiredType().getName()));
        }
        return response;
    }

    @ExceptionHandler({ MissingServletRequestParameterException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public JSONObject requestMissingServletRequest(MissingServletRequestParameterException ex) {
        UtilFunctions.log.error("MissingServletRequestParameterExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        JSONObject response = new JSONObject();
        // response.put("message", "Bad Request");
        String strTemplate = "Bad Request, param:{0} is required, type:{1}";
        response.put("message", MessageFormat.format(strTemplate, ex.getParameterName(), ex.getParameterType()));
        return response;
    }

    @ExceptionHandler({ NoSuchRequestHandlingMethodException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public JSONObject NoSuchRequestHandlingMethodExceptionHandler(NoSuchRequestHandlingMethodException ex) {
        UtilFunctions.log.error("NoSuchRequestHandlingMethodExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        JSONObject response = new JSONObject();
        response.put("message", "Not Found");
        return response;
    }

    /*----- REQUEST ERROR -----*/
    @ExceptionHandler({ HttpMessageNotReadableException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public JSONObject requestNotReadable(HttpMessageNotReadableException ex) {
        UtilFunctions.log.error("HttpMessageNotReadableExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        JSONObject response = new JSONObject();
        response.put("message", "Bad Request");
        return response;
    }

    @ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public JSONObject request405(HttpRequestMethodNotSupportedException ex) {
        UtilFunctions.log.error("HttpRequestMethodNotSupportedExceptionHandler, msg: {}, exception: {}", ex.toString(), ex);
        JSONObject response = new JSONObject();
        // response.put("message", "Method Not Allowed");
        response.put("message", ex.getMessage());
        return response;
    }

    @ExceptionHandler({ JwebException.class })
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public JSONObject jwebExceptionHandler(JwebException ex, HttpServletRequest request) {
        UtilFunctions.log.error("jwebExceptionHandler, info: {}, exception: {}", ex.getMessage(), ex);
        UtilFunctions.reportError("jwebExceptionHandler, " + ex.toString(), null);
        //JSONObject response = new JSONObject();
        //response.put("code", ErrCode.SER_INTERNAL_ERR);
        //response.put("message", ex.getMessage());
        //response.put("message", "The system is busy. Please try again later.");
        ResourceBundle resourceBundle = (ResourceBundle) request.getAttribute("resourceBundle");
        String message = UtilFunctions.getMessage(resourceBundle, "SYSTEM_BUSY");
        return new Response(ErrCode.SER_INTERNAL_ERR, message).toJson();
    }
}

2、springmvc全局异常捕获,整合钉钉打印异常相关信息

  UtilFunctions#reportError()方法:

public static void reportError(String msg, Exception err) {
    if (err != null) {
        log.error("msg:{}, err:{}", msg, err);
    }

    JSONObject content = new JSONObject();
    //content.put("content", "hostname:" + Config.HOSTNAME + "\n" + "errMsg:" + msg);
    content.put("content", "hostname:" + Config.HOSTNAME + "\n" + "errMsg:" + msg + "\n" + getStackTraceInfo(err));

    JSONObject obj = new JSONObject();
    obj.put("msgtype", "text");
    obj.put("text", content.toString());
    String query = obj.toString();
    try {
        URL url = new URL("https://oapi.dingtalk.com/robot/send?access_token=" + Config.DINGTOKEN);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setRequestProperty("Content-Type", "application/json");
        connection.connect();
        try (OutputStream os = connection.getOutputStream()) {
            os.write(query.getBytes("UTF-8"));
        }
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {

        }
        connection.disconnect();

    } catch (Exception e) {
        e.printStackTrace();
    }
}
public static String printStackTraceToString(Throwable t) {
//        StringWriter sw = new StringWriter();
//        t.printStackTrace(new PrintWriter(sw, true));
//        return sw.getBuffer().toString();

    StringWriter sw = null;
    PrintWriter pw = null;
    try {
        sw = new StringWriter();
        pw =  new PrintWriter(sw);
        t.printStackTrace(pw);
        pw.flush();
        sw.flush();
        return sw.getBuffer().toString();
    } finally {
        if (sw != null) {
            try {
                sw.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        if (pw != null) {
            pw.close();
        }
    }
}
public static String getStackTraceInfo(Throwable t) {
    String stackTraceInfo = "";

    String stackTrace = printStackTraceToString(t);
    String regex = "at amberai.jweb(\\S*)";
    Pattern pattern = Pattern.compile(regex);

    Matcher matcher = pattern.matcher(stackTrace);
    while (matcher.find()) {
        stackTraceInfo += matcher.group() + "\n";
        // UtilFunctions.log.info("=====matcher.group:{}" + matcher.group());
    }
    return stackTraceInfo;
}

3、测试

  3.1、手动抛出JwebException

TradeOrder tradeOrder = tradeService.getOrderByHashId(hashId);
if (tradeOrder == null) {
    String errMsg = MessageFormat.format("TradeController#getOrder error, tradeOrder:{0}, uid:{1}", tradeOrder, uid);
    throw new JwebException(errMsg);
}
UtilFunctions.log.info("grpc getOrder info, uid:{}, tradeOrder.getUserid:{}", tradeOrder, uid,
        tradeOrder.getUserid());
if (!uid.equals(tradeOrder.getUserid())) {
    String errMsg = MessageFormat.format("TradeController#getOrder error, uid:{0}, tradeOrder.getUserid:{0}", uid, tradeOrder.getUserid());
    throw new JwebException(errMsg);
}

  

  3.2、代码出现RuntimeException,比如

  int a = 1/0;

原文地址:https://www.cnblogs.com/xy-ouyang/p/10803726.html

时间: 2024-11-02 13:14:08

springmvc请求参数异常统一处理,结合钉钉报告信息定位bug位置的相关文章

SpringMVC请求参数北京PK10平台出租和响应结果全局加密和解密

前段时间在做一个对外的网关项目,涉及到加密和解密模块,这里详细分析解决方案和适用的场景.为了模拟真实的交互场景,先定制一下整个交互流程.第三方传输(包括请求和响应)数据报文包括三个部分: 1.timestamp,long类型,时间戳.2.data,String类型,实际的业务请求数据转化成的Json字符串再进行加密得到的密文.3.sign,签名,生成规则算法伪代码是SHA-256(data=xxx&timestamp=11111),防篡改.为了简单起见,加密和解密采用AES,对称秘钥为"

springmvc请求参数异常处理

接着上一篇<springmvc 通过异常增强返回给客户端统一格式>讲通过spring ControllerAdvice对各种异常进行拦截处理,统一格式返回给客户端. 接下来我们更精细的讲,通过@ExceptionHandler拦截异常,提示参数客户端哪些参数没有传或参数数据类型不一致,方便客户端服务端联调测试. 简述一下上一篇拦截异常主要流程: 1.自定义一个类RestExceptionHandler,并使用@ControllerAdvice注解,表示这个类是控制器增强: 2.在RestExc

springmvc——请求参数获取的几种方法

方法一: 通过@PathVariabl注解获取路径中传递参数 JAVA @RequestMapping(value = "/{id}/{str}") public ModelAndView helloWorld(@PathVariable String id, @PathVariable String str) { System.out.println(id); System.out.println(str); return new ModelAndView("/helloW

springMVC 请求404异常或静态资源无法访问

springMVC 请求404错误或静态资源无法访问问题:springMVC 请求404错误或静态资源无法访问. 在web.xml中我们一般这样配置: spring3 org.springframework.web.servlet.DispatcherServlet 1 spring3 / 使用 / 可以实现rest风格,但是会拦截了所有的请求导致静态资源无法访问(解决方法后面说), 当然,如果你使用*.do.*.xhtml等就不会出现静态资源无法访问问题. 静态资源无法访问解决方案: 1,在s

springmvc请求参数获取的几种方法

1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交. /** * 1.直接把表单的参数写在Controller相应的方法的形参中 * @param username * @param password * @return */ @RequestMapping("/addUser1") public String addUser1(String username,String password) { System.out.pri

SpringMVC请求体参数处理问题

如果请求定义为application/json格式,则要用Spring MVC中@RequestBody参数才能接受(用@RequestParam参数接受会报400错误),但SpringMVC的@RequestBody注解一个方法只能用一个,且接受的是完整的body内容,如前台传递:{id:1},后台接受的参数值也是{id:1},因此必须要做对应的解析处理,所以: 1.一般非必须情况下,用SpringMVC时少用application/json格式的请求. 2.定一个和参数对应的POJO类,或用

SpringMVC之请求参数的获取方式

转载出处:https://www.toutiao.com/i6510822190219264516/ SpringMVC之请求参数的获取方式 常见的一个web服务,如何获取请求参数? 一般最常见的请求为GET和POST,get请求的参数在url上可以获取,post请求参数除了url上还有可能在表单中,文件上传时,获取方式又和一般的参数获取不一样 本篇则主要集中在不同请求方式下,获取参数的使用姿势 首先需要搭建一个后端的请求,为了快速演示 利用spring-boot创建了一个机器简单的工程,依赖版

请求参数到表述层的类型转换——SpringMVC

一.不论是SpringMVC 的 JSR-303 数据校验还是自定义类型转换器,都需要配置 <mvc:annotation-driven/>,而添加这个配置后,会自动注册RequestMappingHandlerMapping. RequestMappingHandlerAdapter 与 ExceptionHandlerExceptionResolver  三个bean.在没添加前,正常的请求都是由 AnnotationMethodHandlerAdapter 进行处理的.我之前 的几篇文章

Springmvc中 同步/异步请求参数的传递以及数据的返回

注意: 这里的返回就是返回到jsp页面 **** controller接收前台数据的方式,以及将处理后的model 传向前台***** 1.前台传递数据的接受:传的属性名和javabean的属性相同 (1).使用基本类型,或引用类型进行接受: @RequestMapping(value="/select") PublicString  select(String name,int age,Model model){ // 这样这里的name,age 就是我们前台传递的参数,也是我们Ja