首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Spring Boot】027-@ControllerAdvice 与 @RestControllerAdvice

【Spring Boot】027-@ControllerAdvice 与 @RestControllerAdvice

作者头像
訾博ZiBo
发布2025-01-06 15:41:53
发布2025-01-06 15:41:53
2.5K00
代码可运行
举报
运行总次数:0
代码可运行

【Spring Boot】027-@ControllerAdvice 与 @RestControllerAdvice

一、@ControllerAdvice概述

1、简介

@ControllerAdvice 是 @Controller 的增强版,其主要用来处理全局数据,一般搭配 @ExceptionHandler 、@ModelAttribute 以及 @InitBinder 使用!

2、使用场景

  • 全局异常处理;
  • 添加全局数据;
  • 请求参数预处理;

二、全局异常处理

1、概述

@ControllerAdvice 最常见的使用场景就是全局异常处理。在文件上传时,有时候文件超过最大限制,就会抛出异常,此时我们可以通过 @Controller 结合 @ExceptionHandler 定义全局异常捕捉机制!

2、代码演示

Thymeleaf几乎不用了,不再演示!

自定义异常处理类 CustomExceptionHandler
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.common.handler;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@ControllerAdvice
public class CustomExceptionHandler {
    
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException{
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.write("上传文件大小超出限制!");
        out.flush();
        out.close();
    }
    
}
resources/static目录下的upload.html
代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFile" value="请选择文件">
    <input type="submit" value="上传">
</form>

</body>
</html>
文件上传处理接口FileUploadController
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.controller.file;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@RestController
public class FileUploadController {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    @PostMapping("upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest request){
        String realPath = request.getSession().getServletContext().getRealPath("/uploadFile/");
        String format = sdf.format(new Date());
        File folder = new File(realPath + format);
        if(!folder.isDirectory()){
            folder.mkdirs();
        }
        String oldName = uploadFile.getOriginalFilename();
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
        try {
            uploadFile.transferTo(new File(folder,newName));
            return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/uploadFile/" + format + "/" + newName;
        }catch (IOException e){
            e.printStackTrace();
        }
        return "上传失败!";
    }
}

3、运行测试

上传正常大小的图片
image-20210817092855131
image-20210817092855131
上传较大的图片
image-20210817092952514
image-20210817092952514

三、添加全局数据

1、概述

@ControllerAdvice 是一个全局数据处理组件,因此也可以在其中配置全局数据,使用 @ModelAttribute 注解进行配置。

2、代码演示

全局数据配置 GlobalConfig
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.config;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalConfig {
    // info表示的是返回数据的key
    @ModelAttribute(value = "info")
    public Map<String,String> userInfo(){
        Map<String,String> map = new HashMap<>();
        map.put("username","刘备");
        map.put("gender","男");
        return map;
    }
}
在Controller中使用全局数据

注意 @RestController 和 @Controller 两个注解的区别!@RestController = @Controller + @ResponseBody 这里就暂时使用 @Controller 吧!因为很少用,所以用一下吧,增强记忆!

代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@Controller
public class HelloController {

    @RequestMapping("hello")
    @ResponseBody
    public Object hello(Model model){
        Map<String, Object> map = model.asMap();
        return map.get("info");
    }

}

3、运行结果

image-20210817094736527
image-20210817094736527

四、请求参数预处理

1、概述

@ControllerAdvice 结合 @InitBinder 实现对请求参数预处理!

2、代码示例

仅作写法展示,未进行实际测试!

实体类:Book
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.entity;

import lombok.Data;

@Data
public class Book {
    private String name;
    private String author;
}
实体类:Author
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.entity;

import lombok.Data;

@Data
public class Author {
    private String name;
    private Integer age;
}
Controller 接收实体类(错误写法)

这么写的问题:book 和 author 中都有 name 属性,会导致数据混淆错误!

代码语言:javascript
代码运行次数:0
运行
复制
    @RequestMapping("hi")
    public String hi(Book book, Author author){
        return book.toString() + "==>" + author.toString();
    }
Controller 接收实体类(正确写法)
代码语言:javascript
代码运行次数:0
运行
复制
    @RequestMapping("hi")
    public String hi(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author){
        return book.toString() + "==>" + author.toString();
    }
GlobalConfig
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.api.config;

import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalConfig {

    @InitBinder("b")
    public void init(WebDataBinder binder){
        binder.setFieldDefaultPrefix("b.");
    }

    @InitBinder("a")
    public void init2(WebDataBinder binder){
        binder.setFieldDefaultPrefix("a.");
    }
}

五、@RestControllerAdvice

1、与 @ControllerAdvice 区别

代码演示省略!

简单地说,@RestControllerAdvice 与 @ControllerAdvice 的区别就和 @RestController 与 @Controller 的区别类似,@RestControllerAdvice 注解包含了 @ControllerAdvice 注解和 @ResponseBody 注解。

当自定义类加@ControllerAdvice注解时,方法需要返回json数据时,每个方法还需要添加@ResponseBody注解;

当自定义类加@RestControllerAdvice注解时,方法自动返回json数据,每个方法无需再添加@ResponseBody注解;

2、@RestController 与 @Controller 的区别

@RestController = @Controller + @ResponseBody

使用@Controller 注解

在对应的方法上,视图解析器可以解析 return 的 jsp,html 页面,并且跳转到相应页面

若返回 json 等内容到页面,则需要加 @ResponseBody 注解;

@RestController注解

相当于 @Controller + @ResponseBody 两个注解的结合,返回 json 数据不需要在方法前面加 @ResponseBody 注解了,但使用@RestController 这个注解,就不能返回 jsp,html 页面,视图解析器无法解析 jsp,html 页面;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【Spring Boot】027-@ControllerAdvice 与 @RestControllerAdvice
  • 一、@ControllerAdvice概述
    • 1、简介
    • 2、使用场景
  • 二、全局异常处理
    • 1、概述
    • 2、代码演示
      • 自定义异常处理类 CustomExceptionHandler
      • resources/static目录下的upload.html
      • 文件上传处理接口FileUploadController
    • 3、运行测试
      • 上传正常大小的图片
      • 上传较大的图片
  • 三、添加全局数据
    • 1、概述
    • 2、代码演示
      • 全局数据配置 GlobalConfig
      • 在Controller中使用全局数据
    • 3、运行结果
  • 四、请求参数预处理
    • 1、概述
    • 2、代码示例
      • 实体类:Book
      • 实体类:Author
      • Controller 接收实体类(错误写法)
      • Controller 接收实体类(正确写法)
      • GlobalConfig
  • 五、@RestControllerAdvice
    • 1、与 @ControllerAdvice 区别
    • 2、@RestController 与 @Controller 的区别
      • 使用@Controller 注解
      • @RestController注解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档