04-响应结果

nobility 发布于 2022-10-11 05-SpringMVC 708 次阅读


响应结果

我所探测到的,支持返回String、ModeAndView、void,ResponseEntity和普通对象类型,若返回其他类型抛出异常,若非要返回其他类型数据可能就需要手写解析器了,比如JSON解析器

返回String类型

  • 使用@ResponseBody注解,表示该方法直接产生响应体数据,不经过视图,用于生成JSON等结构化字符串
  • 类上使用@RestController注解代替@Controller注解,表示该类下的所有方法都会直接返回字符串
  • 若不使用@ResponseBody@RestController注解,直接返回的字符串会被当成请求转发的视图页面
package com;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@Controller
//@RestController
public class Main {
  @GetMapping("/test1")
  @ResponseBody
  public String test1(Integer id) {
    return "id: " + id;
  }

  @GetMapping("/test2")
  public String test2(HttpServletRequest request) {
    request.setAttribute("id", 1);
    return "/index.jsp";  //请求转发到index.jsp
  }

  @GetMapping("/test3")
  public String test3() {
    return "redirect:/index.jsp";  //使用 redirect: 前缀表示重定向
  }
}

使用下面jsp页面进行测试

<a href="${pageContext.request.contextPath}/test1?id=1">/test1?id=1</a><br>
<a href="${pageContext.request.contextPath}/test2">/test2</a><br>
<a href="${pageContext.request.contextPath}/test3?id=1">/test3?id=1</a><br>
<h2>id: ${requestScope.id}</h2>

返回ModelAndView类型

  • 方法返回ModelAndView对象,可向视图中绑定数据,ModelAndView是SpringMVC提供的一个类
package com;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class Main {

  @GetMapping("/test1")
  public ModelAndView test1(Integer id) {
    ModelAndView modelAndView = new ModelAndView("/index.jsp");  //若视图不使用斜杠开头表示使用该类的路径前缀做前缀
    //modelAndView.setViewName("/view.jsp");  //也可使用该方法修改视图
    modelAndView.addObject("id", id);  //默认将属性加入到请求对象上
    return modelAndView;  //返回ModelAndView对象,默认是请求转发方式
  }

  @GetMapping("/test2")
  public ModelAndView test2(Integer id) {
    ModelAndView modelAndView = new ModelAndView("redirect:/index.jsp");  //使用 redirect: 表示重定向
    modelAndView.addObject("id", id);  //重定向,由于是新的请求,所以该数据无法传递到视图
    return modelAndView;
  }
}

使用下面jsp页面进行测试

<a href="${pageContext.request.contextPath}/test1?id=1">/test1?id=1</a><br>
<a href="${pageContext.request.contextPath}/test2?id=1">/test2?id=1</a><br>
<h2>id: ${requestScope.id}</h2>

返回普通对象类型

请使用至少2.9.x版本,因为之前的版本与MySQL同时使用时存在很严重的安全隐患

默认调用对象的toString()方法,为了返回JSON数据,首先需要引入JSON序列化包jackson-databind,之后不需要任何配置,因为Spring全局配置文件中配置过<mvc:annotation-driven/>注解开发模式,由SpringMVC自动创建该类中的转换器对象(该包转换器类实现了HttpMessageConverter接口,转化返回值类型),所以就会自动转化

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>x.x.x</version>
</dependency>

在控制器上类中使用@ResponseBody@RestController注解,并且方法中返回对象时(List集合会转化成JavaScript数组),该组件会自动序列化成JSON格式字符串

下面是简单使用,默认情况下对于时间类型返回的是时间戳,若不想返回时间戳可使用@JsonFormat注解进行格式化(同时设置时区),该注解也可以格式化数字

package com;

import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;

class Student {
  private Integer id;
  private String name;
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
  private Date birthday;
  //setter getter toString 省略
}

@Controller
public class Main {
  @GetMapping("/test")
  @ResponseBody
  public Student test() {
    Student student = new Student();
    student.setId(1);
    student.setName("zs");
    student.setBirthday(new Date());
    return student;
  }
}

返回void类型

使用Servlet中的请求响应对象手动转发

package com;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class Main {
  @GetMapping("/test1")
  public void test1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setAttribute("id", 1);
    request.getRequestDispatcher("/index.jsp").forward(request, response);
  }

  @GetMapping("/test2")
  public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.setAttribute("id", 1);
    response.sendRedirect(request.getContextPath() + "/index.jsp");
  }
}

使用下面jsp页面进行测试

<a href="${pageContext.request.contextPath}/test1">/test1</a><br>
<a href="${pageContext.request.contextPath}/test2">/test2</a><br>
<h2>id: ${requestScope.id}</h2>

返回ResponseEntity类型

用于自定义HTTP响应

package com;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class Main {
  @GetMapping("/test")
  public ResponseEntity<String> get() {  //泛型指定返回类型,泛型也是普通对象,与直接返回普通对象一致
    HttpHeaders headers = new HttpHeaders();  //创建响应头
    headers.setContentType(MediaType.APPLICATION_JSON);  //指定媒体类型
    HttpStatus status = HttpStatus.resolve(200);  //创建响应状态码
    return ResponseEntity  //返回响应对象
        .status(status)  //指定http响应状态码
        .headers(headers)  //指定http响应头
        .body("请求体");   //指定http响应体,对应ResponseEntity的泛型
  }
}
加油啊!即便没有转生到异世界,也要拿出真本事!!!\(`Δ’)/
最后更新于 2022-10-11