Spring Web MVC入门(5)

响应

在我们前面的代码例子中, 都已经设置了响应数据Http响应结果可以是数据, 也可以是静态页面, 也可以针对响应设置状态码, Header信息等.

返回静态页面

创建前端页面index.html(注意路径)

html代码如下:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    Hello, Spring MVC,我是index页面.
</body>
</html>

后台代码如下:

java 复制代码
@RestController
public class IndexController {
    @RequestMapping("/index")
    public Object index() {
        //返回index.html
        return "/index.html";
    }
}

运行结果:

结果却发现, 页面未正确返回, http响应把"/index.html"当作http响应正文的数据. 那么Spring MVC如何才能识别出来index.html是一个静态页面, 并进行返回呢?

我们需要把@RestController 改为 @Controller.

正确代码如下:

java 复制代码
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index() {
        //返回index.html
        return "/index.html";
    }
}

再次运行得到结果:

发现页面正确展示了.

@RestController和@Controller的关系

我们之前讲过了MVC模式, 后端会返回视图, 这是早期时的概念

随着互联网的发展, 目前项目流行"前后端分离模式" , Java主要是用来做后端项目的开发, 所以就不再处理前端相关内容了.

MVC的概念也逐渐发生了变化, View不再返回视图, 而是返回显示视图时所需要的数据.

所以前面的@RestController其实是返回的数据, 是作为一个复合注解.

@RestController = @Controller(默认返回视图) + @ResponseBody(返回数据).

@Controller:定义一个控制器, Spring框架启动时加载, 把这个对象交给Spring管理.

@ResponseBody: 定义返回的数据为非视图, 返回一个text/html信息. 它既可以修饰类, 又可以修饰方法. (修饰类时:表示当前类的所有方法, 全部返回数据, 和@Controller可以合并为@RestController; 修饰方法时, 表示当前方法返回数据).

如果想返回视图的话, 只需要把@ResponseBody去掉就可以了, 也就是@Controller.

返回数据@ResponseBody

上面我们讲到, @ResponseBody表示返回数据.

java 复制代码
@Controller
@ResponseBody
public class IndexController {
    @RequestMapping("/index")
    public Object index() {
        //返回index.html
        return "/index.html";
    }
}

加上@ResponseBody注解, 该方法就会把"/index.html"当作一个数据返回给前端.

@ResponseBody既是类注解, 又是方法注解

如果作用在类上, 表示该类的所有方法, 返回的就是数据, 如果作用在方法上, 表示该方法返回的就是数据.

当你在一个类中既想让一些方法返回视图, 又想让一些方法返回数据, 那么就可以给类加@Controller注解, 给想返回数据的方法加上@ResponseBody注解, 返回视图的方法不处理即可.

同样, 如果类上有@RestController注解时:表示所有方法上添加了@ResponseBody注解, 也就是当前类下所有方法返回值作为响应数据.

java 复制代码
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index() {
        //返回index.html
        return "/index.html";
    }

    @RequestMapping("/returnData")
    @ResponseBody
    public String returnData() {
        return "该方法返回数据";
    }
}

多个注解时, 没有先后顺序, 先写哪个都可以.

如果给第二个方法去掉@Responsebody, 程序就会报404错误.

因为程序会认为返回的应该是视图, 就会根据内容去查找文件, 但是文件查找不到, 路径不存在, 就报404.

返回HTML代码片段

后端返回数据的时候, 如果数据中有HTML代码, 也会被浏览器解析.

java 复制代码
    @RequestMapping("/returnHtml")
    @ResponseBody
    public String returnHtml() {
        return "<h1>hello HTML~</h1>";
    }

运行结果:

通过Fiddler观察结果, Content-Type为 text/html.

响应中的Content-Type常见取值有以下几种:

text/html:body数据格式是HTML

text/css:body数据格式是CSS

application/javascript:body数据格式是JavaScript

application/json:body数据格式是JSON.

返回JSON

Spring MVC也可以返回JSON

后端方法返回结果为对象.

java 复制代码
    @RequestMapping("/returnJson")
    @ResponseBody
    public HashMap<String, String> returnJson() {
        HashMap<String, String> map = new HashMap<>();
        map.put("Java", "Java value");
        map.put("MySQL", "MySQL value");
        map.put("Redis", "Redis value");
        return map;
    }

运行结果:

通过Fiddler观察响应结果, Content-Type为application/json.

设置状态码

Spring MVC会根据我们方法的返回结果自动设置响应状态码, 程序员也可以手动指定状态码.

通过Spring MVC的内置对象HttpServletResponse提供的方法来进行设置.

java 复制代码
    @RequestMapping("/setStatus")
    @ResponseBody
    public String setStatus(HttpServletResponse response) {
        response.setStatus(418);
        return "设置状态码成功";
    }

运行结果:

通过Fiddler观察设置的结果:

设置Header

Http响应报头也会向客户端传递一些附加信息, 比如服务程序的名称, 请求的资源已移动到新地址等, 如:Content-Type, Local等.

这些信息通过@RequestMapping注解的属性来实现.

先来看@RequestMapping的源码:

java 复制代码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective({ControllerMappingReflectiveProcessor.class})
public @interface RequestMapping {
    String name() default "";

    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};

    RequestMethod[] method() default {};

    String[] params() default {};

    String[] headers() default {};

    String[] consumes() default {};

    String[] produces() default {};
}

1.value:指定映射的URL.

2.method:指定请求的method类型, 如GET, POST等.

3.consumes:指定请求(request)的提交内容类型(Content-Type), 例:application/json, text/html;

4.produces:指定返回的内容类型, 仅当request请求头中的(Accept)类型中包含该指定类型才返回

5.Params: 指定request中必须包含某些参数值时, 才让该方法处理.

6.headers:指定request中必须包含某些指定的header值, 才能让该方法处理请求.

设置Content-Type

我们通过设置produces属性的值, 设置响应的报头Content-Type.

java 复制代码
    @RequestMapping(value = "/returnJson2", produces = "application/json")
    @ResponseBody
    public String returnJson2() {
        return "{\"sucess\":true}";
    }

运行结果:

Fidder抓包结果:

如果不设置produces, 方法返回的结果为String时, Spring MVC默认返回类型, 是text/html.

设置其他Header

设置其它Header的话, 需使用Spring MVC内置对象HttpServletResponse提供的方法来进行设置.

java 复制代码
    @RequestMapping("/setHeader")
    @ResponseBody
    public String setHeader(HttpServletResponse response) {
        response.setHeader("MyHeader", "MyHeaderValue");
        return "设置Header成功";
    }

void setHeader(String name, String value)设置一个带有给定的名称和值的Header. 如果name已经存在, 则覆盖旧的值.

运行成功后查看Fidder抓包结果:

相关推荐
前端大卫20 分钟前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘36 分钟前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare37 分钟前
浅浅看一下设计模式
前端
Lee川40 分钟前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix1 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人1 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl1 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人1 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼1 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端