Spring Web MVC入门(3)——响应

目录

一、返回静态页面

@RestController 和 @Controller之间的关联和区别

二、返回数据@ResponseBody

@ResponseBody作用在类和方法的情况

三、返回HTML代码片段

响应中的Content-Type常见的取值:

四、返回JSON

五、设置状态码

六、设置Header

1、设置Content-Type

2、设置其他Header


一、返回静态页面

        创建前端页面,要创建路径的路径如下:

        

        前端代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Index页面</title>
</head>
<body>Hello,Spring MVC,我是Index⻚⾯
</body>
</html>

        后端代码:

@RestController
@RequestMapping("/res")
public class ResponseController {@RequestMapping("/index")public String index() {return "/index.html";}

        浏览器访问:http:127.0.0.1:8080/res/index ,页面如下:

        

        结果发现,页面不是我们想要的,而是直接返回了一个字符串,那么就说明,Spring MVC没有识别我们返回的是一个前端页面,那么怎么让它识别出来是 /index.html 文件,而不是字符串呢?那就需要把注解@RestController改为@Controller,正确代码如下:

@Controller
@RequestMapping("/res")
public class ResponseController {@RequestMapping("/index")public String index() {return "/index.html";}
}

        浏览器再访问一次:http:127.0.0.1:8080/res/index ,页面如下:

        

        就是我们想要的页面了。

@RestController 和 @Controller之间的关联和区别

        前面讲的MVC模式,后端会返回视图,这是早期的概念,但随着互联网的发展,项目流行 “前后端分离” 模式,Java主要用来做后端项目,所以也就不再处理前端相关的内容了。

        如上图,MVC也随之发生改变,View不再返回视图,而是返回显示视图所需要的数据,所以前面使用的@RestController返回的就是数据

@RestController = @Controller + @ResponseBody

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

@ResponseBody定义返回数据格式为非视图,返回一个text / html信息

        源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {@AliasFor(annotation = Controller.class)String value() default "";
}

        也就是说 @RestController 或 (@Controller + @ResponseBody)注解返回的是前端所需要的数据@Controller 返回的是视图


二、返回数据@ResponseBody

        上面说到,@ResponseBody 表示返回数据,代码如下:

@Controller
@RequestMapping("/res")
public class ResponseController {@ResponseBody@RequestMapping("/index")public String index() {return "/index.html";}
}

        因为加上了@ResponseBody注解,所以index方法就会把 “/index.html” 当做一个数据返回给前端,浏览器页面如下:

        

@ResponseBody作用在类和方法的情况

        @ResponseBody作用在类上,表示该类上的所有方法,返回的都是数据

        @ResponseBody作用在方法上,表面该方法返回的是数据

1、也就是说明在类上添加注解@ResponseBody,相当于该类上所有的方法都添加了注解@ResponseBody

2、因为@RestController = @Controller + @ResponseBody,所以如果类上添加了注解@RestController,相当于该类的所有方法都添加了注解@RestController

3、如果一个类里面,既要返回数据,又要返回视图,那么就使用注解@Controller添加在该类上,然后需要返回数据的方法添加注解@ResponseBody,返回视图的方法就不同管它

        一个方法是返回视图,一个方法是返回数据,代码如下:

@Controller
@RequestMapping("/res")
public class ResponseController {@RequestMapping("/index")public String index() {return "/index.html";}@ResponseBody@RequestMapping("returnData")public String returnData() {return "该方法返回数据";}
}

        多个注解修饰 类 / 方法,没有先后顺序,谁先谁后都行,

        浏览器分别访问http:127.0.0.1:8080/res/index 和http:127.0.0.1:8080/res/returnData,页面分别如下:

        如果returnData方法删去注解@ResponseBody,代码如下:

@Controller
@RequestMapping("/res")
public class ResponseController {@RequestMapping("/index")public String index() {return "/index.html";}@RequestMapping("returnData")public String returnData() {return "该方法返回数据";}
}

        在访问一下:http:127.0.0.1:8080/res/returnData ,页面如下:

        404错误码,因为该类是注解@Controller修饰的,访问该类的方法默认返回的是视图,程序就会认为需要返回视图(returnData方法没加@ResponseBody注解),然后根据内容进行查找文件,但查询不到,也就是路径不存在,所以报错404


三、返回HTML代码片段

        后端返回数据时,如果数据有HTML代码,也会被浏览器解析,代码如下:

    @ResponseBody@RequestMapping("/returnHtml")public String returnHtml() {return "<h1> Hello, HTML</h1>";}

        浏览器访问:http:127.0.0.1:8080/res/returnHtml ,页面如下:

        通过fiddler观察Content-Type,如图:

响应中的Content-Type常见的取值:

1、text / htmlbody数据格式是 HTML

2、text / cssbody数据格式是 CSS

3、application / Javascriptbody数据格式是 JavaScript

4、application / jsonbody数据格式是 JSON

如果请求的是js文件,Spring MVC会自动设置Content-Type为 application / Javascript

如果请求是css文件,Spring MVC会自动设置Content-Type为 text / css


四、返回JSON

        Spring MVC也可以返回JSON,后端方法返回结果为对象(下面使用Hash对象),代码如下:

    @ResponseBody@RequestMapping("/returnJson")public HashMap<String, String> returnJson() {HashMap<String, String> map = new HashMap<>();map.put("key1", "value1");map.put("key2", "value2");map.put("key3", "value3");return map;}

        浏览器访问:http:127.0.0.1:8080/res/returnJson ,页面如下:

        

        使用fiddler抓包观察:


五、设置状态码

        Spring MVC会根据我们方法的返回结果自动设置响应状态码,程序员也可以手动指定状态码,通过Spring MVC的内置对象HttpServletResponse提供的方法来进行设置

        代码如下:

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

        浏览器访问:http:127.0.0.1:8080/res/setStatus ,页面如下:

        

        可以看到,状态码并不影响页面的展示

        通过fiddler抓包看看,如图:


六、设置Header

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

        这些信息通过@RequestMapping注解的属性来实现,如下是@RequestMapping的源码

@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值,才让该方法处理请求

        了解即可,更多说明参考:Mapping Requests :: Spring Framework

1、设置Content-Type

        通过设置produces属性的值,可以设置响应的报头Content-Type,代码如下:

    @ResponseBody@RequestMapping(value = "/setContentType", produces = "application/json")public String returnJson2() {return "{\"ok\":1}";}

        浏览器访问:http:127.0.0.1:8080/res/setContentType ,页面如下:

        

        通过Postman测试,页面如下:

        

        可以看到Postman识别出来了响应的报头Content-Type是JSON。

        通过fiddler抓包观察:

        也是JSON格式,如果不进行设置produces,方法返回结果为String时,Spring MVC默认返回的text/html。

        设置返回类型时,也可以同步设置响应编码,代码如下:

  @ResponseBody@RequestMapping(value = "/setContentType", produces = "application/json;charset=utf-8")public String returnJson2() {return "{\"ok\":1}";}

        fiddler抓包结果:

2、设置其他Header

        设置其他Header的话,需要使用 Spring MVC的内置对象HttpServletResponse提供的方法来进行设置。代码如下:

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

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

        浏览器访问:http:127.0.0.1:8080/res/setHeader ,页面如下:

        

        通过Postman抓包,如图:

        确实设置成功了。


都看到这了,点个赞再走吧,谢谢谢谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/4524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】---STL容器适配器之底层deque浅析

【C】---STL容器适配器之底层deque浅析 一、deque的使用二、deque的原理1、deque的结构2、deque的底层结构&#xff08;1&#xff09;deque的底层空间&#xff08;2&#xff09;deque如何支持随机访问、deque迭代器 3、deque的优缺点&#xff08;1&#xff09;deque的优势&…

java基础之java容器-Collection,Map

java容器 java容器分类一. Collection1. List①. ArrayList② . LinkedList③ . Vector 2. Queue队列①. LinkedList②. PriorityQueue 3. Set集合①. HashSet②. TreeSet 二. Map1. HashMap2.TreeMap3. Hashtable java容器分类 java容器分为两大类&#xff0c;分别是Collecti…

代码随想录算法训练营第五十三天|1143.最长公共子序列 、 1035.不相交的线、 53. 最大子序和

1143 题目&#xff1a; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些…

探索区块链世界:赋能创新,揭示区块链媒体发稿的影响力-世媒讯

区块链&#xff0c;这个由“区块”和“链”组成的概念&#xff0c;可能在您眼中充满神秘和复杂&#xff0c;但其实甚至无所不在&#xff0c;它正静悄悄地改变着我们日常生活的方方面面&#xff0c;从金融到媒体&#xff0c;从医疗到教育。 我们来揭开区块链的神秘面纱。区块链…

VRRP基础

1.基本概念 VRRP(Virtual Router Redundancy protocol,虚拟路由冗余协议&#xff09; VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。 VRRP协议版本为VRRPv2&…

SQLServer条件查询,排序

一.常用的运算符 &#xff1a;相等 !&#xff1a;不等 >&#xff1a;大于 <&#xff1a;小于 >&#xff1a;大于等于 <&#xff1a;小于等于 IS NULL&#xff1a;为空 IS NOT NULL&#xff1a;不为空 in&#xff1a;在其中 like&#xff1a;模糊查询 BE…

Java多线程基础

Java多线程 文章目录 Java多线程一、线程介绍及相关概念二、创建和启动线程2.1 Thread类的常用结构2.2 创建线程法1&#xff1a;继承Thread类&#xff08;分配线程对象&#xff09;2.3 创建线程法2&#xff1a;实现Runnable接口&#xff08;创建线程的目标对象&#xff09;2.4 …

揭示C++设计模式中的实现结构及应用——行为型设计模式

简介 行为型模式&#xff08;Behavioral Pattern&#xff09;是对在不同的对象之间划分责任和算法的抽象化。 行为型模式不仅仅关注类和对象的结构&#xff0c;而且重点关注它们之间的相互作用。 通过行为型模式&#xff0c;可以更加清晰地划分类与对象的职责&#xff0c;并…

易错知识点(学习过程中不断记录)

快捷键专区&#xff1a; 注释&#xff1a;ctrl/ ctrlshift/ 保存&#xff1a;ctrls 调试&#xff1a; 知识点专区&#xff1a; 1基本数据类型 基本数据类型有四类&#xff1a;整型、浮点型、字符型、布尔型&#xff08;Boolean&#xff09;&#xff0c; 分为八种&#xff…

JS判断元素是否在数组中

在JavaScript中&#xff0c;有多种方法可以用来判断一个元素是否存在于数组中。以下是其中的一些方法&#xff1a; 1. 使用 Array.prototype.includes() 方法 includes() 方法用于判断一个数组是否包含一个指定的值&#xff0c;根据情况&#xff0c;如果需要区分大小写&#…

AI图书推荐:《企业AI转型:如何在企业中部署ChatGPT?》

Jay R. Enterprise AI in the Cloud. A Practical Guide...ChatGPT Solutions &#xff08;《企业AI转型&#xff1a;如何在企业中部署ChatGPT&#xff1f;》&#xff09;是一本由Rabi Jay撰写、于2024年由John Wiley & Sons出版的书籍&#xff0c;主要为企业提供实施AI转型…

半导体厂FDC系统 的trace data知识

01、什么是FDC系统 在半导体行业中,FDC系统通常指的是"Failure Data Collection"(故障数据收集)系统。FDC系统的作用是收集、存储和分析在半导体制造过程中检测到的故障或不良品数据。以下是FDC系统的一些关键作用: 1. **故障检测**:FDC系统可以实时监测生产线…

python facebook business SDK campaign 广告复制方法

facebook广告复制调试了一天&#xff0c;特此记录&#xff0c;广告复制分为两个步骤&#xff1a; 第一步&#xff1a;使用campaign.create_copy()复制广告系列。 第二步&#xff1a;复制源广告广告集&#xff08;ad_set&#xff09;如果广告集需要修改&#xff0c;使用api_upd…

(六)Servlet教程——JSP与Servlet的关系

JSP与Servlet的关系 JSP&#xff08;Java Server Pages&#xff09;是继Servlet后Sun公司推出的新技术。JSP技术在传统的HTML文件中插入Java程序段和JSP标记&#xff0c;从而形成JSP文件&#xff08;*.jsp&#xff09;。用JSP开发的Web应用是跨平台的&#xff0c;既能在Window…

数据结构与算法目录

1、基本认识 算法的复杂度和稳定性 链接&#xff1a;算法的复杂度和稳定性_o(1) < o(logn) < o(n) < o(nlogn) < o(n^2) < o(n^3)-CSDN博客Java的链表的创建、插入、修改、删除、查询等 链接&#xff1a;Java的链表的创建、插入、修改、删除、查询等_java链表查…

some术语

1.PS_HOLD: DI. Power supply hold control input (电源保持控制输入) (VRM) 电压调节器模块 icache用来缓存指令&#xff0c; dcache用来缓存数据 双85&#xff1a;85度的温度,85%的湿度老化测试 SMPL&#xff1a;Sudden momentary power loss。大概就是“突然掉电的意思…

Python实现视频转音频

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、moviepy实现视频转音频 github地址&#xff1a;GitHub - Zulko/moviepy: Video editing with Python 二、示例代码 ""&…

2024.4.28

有以下类&#xff0c;完成特殊成员函数 #include <iostream>using namespace std; class Person{string name;int* age; public:Person():name("zhangsan"),age(new int(18)){}Person(string name,int* age):name(name),age(new int(*age)){}~Person(){delete…

接口测试-笔记

Date 2024年4月23日21:19:51 Author KarrySmile 1. 前言 因为想更加规范地开发接口&#xff0c;同时让自己测试接口的时候更加高效&#xff0c;更好地写好接口文档。所以学习黑马的《接口自动化测试》课程。链接&#xff1a;黑马程序员软件测试接口自动化测试全套视频教程&a…

Redis运维篇-快速面试笔记(速成版)

文章目录 1. Redis的持久化1.1 RDB&#xff08;快照模式&#xff09;1.2 AOF 模式 2. Redis主从模型&#xff08;高可用&#xff09;2.1 Redis的主从复制2.2 Redis拓扑结构 3. Redis集群模式&#xff08;高并发&#xff09;3.1 Redis的Slots3.2 集群模式的常用命令3.3 多主多从…