【springboot入门-返回处理器(ReturnValueHandler)】

处理类型

  • 视图名称
    • 当方法返回一个字符串,且该字符串不是ResponseEntity或@ResponseBody注解的返回值时,它通常被视为视图名称。Spring MVC将使用配置的ViewResolver来解析这个视图名称,并生成视图
    @Controller
    public class ViewController {
        @GetMapping("/viewName")
        public String viewName() {
            return "myView"; // 视图解析器将解析为 /WEB-INF/views/myView.jsp
        }
    }
    
  • ModelAndView对象
    • 当方法返回一个ModelAndView对象时,Spring MVC会使用该对象中的数据来渲染视图
    @Controller
    public class ModelAndViewController {
        @GetMapping("/modelAndView")
        public ModelAndView modelAndView() {
            ModelAndView mav = new ModelAndView();
            mav.setViewName("myView");
            mav.addObject("message", "Hello, ModelAndView!");
            return mav;
        }
    }
    
  • Map或Model对象
    • 返回的Map或Model对象包含了要传递给视图的属性。Spring MVC会将这些属性添加到模型中,并使用默认或指定的视图名称来渲染视图
    @Controller
    public class ModelController {
        @GetMapping("/model")
        public String model(Model model) {
            model.addAttribute("message", "Hello, Model!");
            return "myView";
        }
    }
    
  • 域对象
    • 返回的域对象(如DTOs或Entity对象)通常会通过消息转换器(如Jackson)转换为JSON或XML格式的响应体,并标注为@ResponseBody
    @RestController
    public class DomainObjectController {
        @GetMapping("/domainObject")
        public User getUser() {
            User user = new User("John Doe");
            return user; // Jackson会自动将其转换为JSON
        }
    }
    
  • @ResponseBody注解
    • 当方法的返回值被@ResponseBody注解时,Spring MVC会将返回值转换为HTTP响应体。这通常用于RESTful服务
    @RestController
    public class ResponseBodyController {
        @GetMapping("/responseBody")
        public @ResponseBody String responseBody() {
            return "Hello, @ResponseBody!";
        }
    }
    
  • ResponseEntity对象
    • 当方法返回一个ResponseEntity对象时,Spring MVC会使用该对象中的HTTP状态码、头部信息和响应体来构建HTTP响应
    @RestController
    public class ResponseEntityController {
        @GetMapping("/responseEntity")
        public ResponseEntity<String> responseEntity() {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Custom-Header", "Value");
            return new ResponseEntity<>("Hello, ResponseEntity!", headers, HttpStatus.OK);
        }
    }
    
  • HttpEntity对象
    • 类似于ResponseEntity,但通常用于只包含响应体和头部信息,而不设置状态码
    @RestController
    public class HttpEntityController {
        @GetMapping("/httpEntity")
        public HttpEntity<String> httpEntity() {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Custom-Header", "Value");
            return new HttpEntity<>("Hello, HttpEntity!", headers);
        }
    }
    
  • void或null
    • 当方法返回void或null时,Spring MVC不会向客户端发送响应体,但可以设置响应的头部信息
@Controller
public class VoidController {
    @GetMapping("/void")
    public void voidMethod(HttpServletResponse response) {
        response.setStatus(HttpStatus.NO_CONTENT.value());
    }
}
  • HTTP状态码
    • 有时,你可能想要直接返回一个HTTP状态码,而不是数据。这可以通过抛出异常(如ResponseStatusException)来实现
@RestController
public class StatusCodeController {
    @GetMapping("/status")
    public ResponseEntity<String> status() {
        return ResponseEntity.status(HttpStatus.CREATED).body("Resource created successfully");
    }
}
  • 异常
    • 如果Controller方法抛出了异常,Spring MVC会使用异常处理器(@ExceptionHandler)来处理这些异常,并生成相应的响应
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ArithmeticException.class)
    public ResponseEntity<String> handleArithmeticException(ArithmeticException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Math error: " + ex.getMessage());
    }
}
  • 异步处理
    • 对于异步处理,你可以返回Callable、DeferredResult或CompletableFuture等类型的对象,Spring MVC会等待异步操作完成后再发送响应
@RestController
public class AsyncController {
    @GetMapping("/async")
    public CompletableFuture<String> asyncMethod() {
        return CompletableFuture.supplyAsync(() -> {
            // 模拟长时间运行的任务
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Hello, Async!";
        });
    }
}
  • 文件下载
    • 如果需要处理文件下载,可以返回Resource对象或使用ResponseEntity与Resource对象一起,来提供文件内容和必要的头部信息
@RestController
public class FileDownloadController {
    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile() {
        Resource resource = new ClassPathResource("static/files/sample.txt");
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
    }
}

源码分析

  1. HandlerAdapter接口:
    HandlerAdapter接口定义了处理请求的方法,handle方法用于处理请求并返回一个ModelAndView对象。

  2. RequestMappingHandlerAdapter类:
    RequestMappingHandlerAdapter是HandlerAdapter的一个实现,它负责处理用@RequestMapping注解的方法。
    它使用了HandlerMethodReturnValueHandler接口的实现来处理Controller方法的返回值。

  3. HandlerMethodReturnValueHandler接口:
    这个接口定义了handleReturnValue方法,用于处理Controller方法的返回值。
    Spring MVC提供了多种默认的返回值处理器,例如ModelAndViewMethodReturnValueHandler、
    ViewMethodReturnValueHandler、ResponseEntityMethodReturnValueHandler等。

  4. 处理视图名称和ModelAndView对象:
    如果方法返回一个String,它通常被视为视图名称,ViewMethodReturnValueHandler会处理这个返回值。
    如果方法返回一个ModelAndView对象,ModelAndViewMethodReturnValueHandler会处理这个返回值。

  5. 处理@ResponseBody和域对象:
    当方法返回一个域对象且没有@ResponseBody注解时,Spring MVC会使用ServletModelAttributeMethodProcessor来处理返回值。
    如果方法返回的域对象上有@ResponseBody注解,ServletInvocableHandlerMethod会直接将对象写入响应体,通常使用消息转换器(如Jackson)将对象转换为JSON。

  6. 处理ResponseEntity对象:
    ResponseEntityMethodProcessor处理器会处理返回ResponseEntity对象的情况,它允许你完全控制响应的头部、状态码和体。

  7. 处理void或null:
    如果方法返回void或null,EmptyReturnValueHandler处理器会被调用来处理这种情况,通常不会向客户端发送任何响应体。

  8. 处理异常:
    ExceptionMethodReturnValueHandler处理器会处理抛出的异常,它通常会将异常转换为错误页面或JSON响应。

  9. 异步处理:
    对于异步返回类型(如Callable、DeferredResult、CompletableFuture),ServletAsyncHandlerMethodReturnValueHandler处理器会处理这些返回值,并在异步操作完成后发送响应。

  10. 文件下载:
    ResourceMethodReturnValueHandler处理器会处理返回Resource对象的情况,它负责处理文件下载。
    在RequestMappingHandlerAdapter的invokeHandlerMethod方法中,会调用extendInterceptors方法来获取返回值处理器链,并根据Controller方法的返回值类型选择合适的处理器来处理返回值。

这些处理器的注册通常发生在RequestMappingHandlerAdapter的初始化过程中,通过afterPropertiesSet方法或通过实现BeanFactoryPostProcessor接口的RequestResponseBodyAdviceAdapterRegistry类来完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值