当前位置: 代码网 > it编程>编程语言>Java > SpringBoot如何设置404、500返回统一格式json

SpringBoot如何设置404、500返回统一格式json

2024年08月09日 Java 我要评论
springboot默认访问不存在资源就会出现404解决后:主要是添加下面配置:# 自定义#出现错误时, 直接抛出异常spring.mvc.throw-exception-if-no-handler-

springboot默认访问不存在资源就会出现404

解决后:

主要是添加下面配置:

# 自定义
#出现错误时, 直接抛出异常
spring.mvc.throw-exception-if-no-handler-found=true
#不要为我们工程中的资源文件建立映射
spring.web.resources.add-mappings=false

全局处理异常:

package com.qykhhr.dujiaoshouservice.exceptionhandler;

import com.qykhhr.dujiaoshouservice.util.r;
import lombok.extern.slf4j.slf4j;
import org.springframework.web.bind.annotation.controlleradvice;
import org.springframework.web.bind.annotation.exceptionhandler;
import org.springframework.web.bind.annotation.responsebody;

import java.sql.sqlintegrityconstraintviolationexception;

/**
 * 异常处理机制
 * 先找到特定异常处理机制,如果没有就会调用exception异常处理机制
 */
@controlleradvice
@slf4j
public class globalexceptionhandler {

    /**
     * 指定出现什么异常来执行这个方法
     * @param e
     * @return
     */
    @exceptionhandler(exception.class)
    @responsebody
    public r error(exception e){
        e.printstacktrace();
        if (e instanceof sqlintegrityconstraintviolationexception){
            return r.error().message("数据库主键冲突,如是本人,请联系管理员");
        }else if (e instanceof org.springframework.web.servlet.nohandlerfoundexception){
            return r.error().message("找不到资源,/(ㄒoㄒ)/~~");
        }
        return r.error().message("内部服务器错误,/(ㄒoㄒ)/~~!");
    }

    /**
     * 自定义异常处理
     * @param e
     * @return
     */
    @exceptionhandler(dujiaoshouexception.class)
    @responsebody
    public r error(dujiaoshouexception e){
        log.error(e.getmessage());
        e.printstacktrace();
        return r.error().code(e.getcode()).message(e.getmsg());
    }
}

统一结果返回:

package com.qykhhr.dujiaoshouservice.util;

import lombok.data;

import java.util.hashmap;
import java.util.map;

/**
 * 统一返回结果的类
 * @author 雨林
 */
@data
public class r {

    private boolean success;
    private integer code;
    private string message;
    private map<string,object> data = new hashmap<>();

    // 把构造方法私有化,只能使用提供的静态方法
    private r(){

    }

    // 成功静态方法
    public static r ok(){
        r r = new r();

        r.setsuccess(true);
        r.setcode(resultcode.success);
        r.setmessage("成功");
        return r;
    }

    // 失败静态方法
    public static r error(){
        r r = new r();

        r.setsuccess(false);
        r.setcode(resultcode.error);
        r.setmessage("失败");
        return r;
    }

    public r message(string message){
        this.setmessage(message);
        return this;
    }

    public r code(integer code){
        this.setcode(code);
        return this;
    }

    public r data(map<string, object> map){
        this.setdata(map);
        return this;
    }

    public r data(string key, object value){
        this.data.put(key, value);
        return this;
    }
}

我有发现了一个问题,因为我配置了映射,当我访问upload请求找不到文件时,依旧返回了spingboot的默认404页面。

我的理解就是访问/upload请求时,springboot会自动到映射的文件夹里面去寻找文件,就会以为这个请求已经被处理了,就不会报找不到处理的异常。而是报除了/error请求的错误。

upload.image.path=/util/images/
upload.apk.path=/util/apk/
upload.crash.exception.file.path=/util/crash/
/**
 * 资源映射路径,只能配置一个映射
 */
@configuration
public class mywebmvcconfigurer extends webmvcconfigureradapter {
    @value("${upload.file.path}")
    private string uploadpath;

    @value("${upload.image.path}")
    private string uploadimagepath;

    @value("${upload.crash.exception.file.path}")
    private string uploadcrashexceptionfilepath;

    @value("${upload.apk.path}")
    private string uploadapkpath;

    /**
     * 将d:\\upload下的文件映射到当前项目/upload/下
     * @param registry
     */
    @override
    public void addresourcehandlers(resourcehandlerregistry registry) {

        registry.addresourcehandler("/favicon.ico").addresourcelocations("classpath:/static/");

        //addresourcehandler()里配置需要映射的文件夹,此处代表映射文件夹user下的所有资源。
        //addresourcelocations()配置文件夹在系统中的路径,使用绝对路径,格式为“file:你的路径/” 后面的 / 必须加上,否则映射失效
//        registry.addresourcehandler("/upload/**").addresourcelocations("file:d:/dujiaoshouapp/");
//        registry.addresourcehandler("/upload/**").addresourcelocations("file:"+uploadpath);
        registry.addresourcehandler("/upload/images/**").addresourcelocations("file:"+uploadimagepath);
        registry.addresourcehandler("/upload/crash/**").addresourcelocations("file:"+uploadcrashexceptionfilepath);
        registry.addresourcehandler("/upload/apk/**").addresourcelocations("file:"+uploadapkpath);
    }
}

解决

可以看到springboot最终保留了/error请求作为后备,未解决的请求都会走到/error路径里面,我们可以定义一个拦截器,拦截这个/error请求,转到我们自己定义的请求里面。

@component
public class exceptioninterceptor implements handlerinterceptor {

    @autowired
    private redistemplate redistemplate;


    @override
    public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview) throws exception {
        if (modelandview != null){
            // 防止出现空指针
            // 请求转到 / 
            modelandview.setviewname("/");
        }
    }
}

然后在webconfig里面配置上拦截器

@configuration
public class mywebmvcconfigurer extends webmvcconfigureradapter {
    @autowired
    private exceptioninterceptor exceptioninterceptor;

    @override
    public void addinterceptors(interceptorregistry registry) {
        registry.addinterceptor(exceptioninterceptor);
        super.addinterceptors(registry);
    }

最后再定义一个controller,处理 / 请求

package com.qykhhr.dujiaoshouservice.controller;

import com.qykhhr.dujiaoshouservice.util.r;
import lombok.extern.slf4j.slf4j;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@restcontroller
@slf4j
public class exceptioncontroller {

    @requestmapping("/")
    public r error() {
        log.info("处理 /error 请求");
        return r.error().message("访问资源无效!");
    }
}

可以看到访问的结果:

ok,我们现在完全是统一的返回格式了~!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com