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,我们现在完全是统一的返回格式了~!
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论