【SpringBoot 2】(八)数据响应 页面响应

写在前面在这里插入图片描述🛫更多知识总结见SpringBoot 2专栏
🚕本篇知识点总结自尚硅谷雷神的视频
🚒博主对于该知识尚在学习阶段
🚄如果发现存在问题请毫不吝啬的指出
🚀🚀扎哇太枣糕的博客首页🚀🚀

文章目录

  • 1 数据响应
    • 1.1 数据响应(JSON为例)
    • 1.2 数据响应之内容协商
  • 2 页面响应
    • 2.1 模板引擎之Thymeleaf
    • 2.2 拦截器
    • 2.3 文件上传

1 数据响应

在这里插入图片描述  数据响应一般分为两种:页面响应和数据响应,一般来说页面响应是用来开发一些单体项目(也就是前后端都在一个开发工具中),而数据响应则是用来进行前后端分离开发的项目,前端发送过来请求后端响应相应的数据。

1.1 数据响应(JSON为例)

  如果想让SpringMVC响应返回一个JSON类型的数据,首先需要在项目的pom.xml文件中导入web场景的启动器

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!--web场景的启动器的底层导入了JSON的开发场景-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-json</artifactId><version>2.6.4</version><scope>compile</scope>
</dependency>

  其次就是在controller中加入@ResponseBody注解,这样的话就是响应数据而不是页面跳转,或者将controller上的@Controller注解换成@RestController,相当于这个controller下的所有方法都自动加上了@ResponseBody注解。在这里插入图片描述

1.2 数据响应之内容协商

  内容协商: 服务器会根据客户端接收能力的不同,返回不同媒体类型的数据。
  原理: 前端发送请求的时候请求头携带Accept字段,用于服务器声明自己(客户端)能够接收的数据类型。
  处理流程: 首先判断当前响应头中是否已经有之前处理时缓存的媒体类型,如果没有的话就是第一次处理需要确定处理的媒体类型,通过Accept字段获取客户(PostMan、浏览器)支持接收的内容类型。经过遍历循环所有当前系统的MessageConverter看谁支持操作这个对象(Person),找到支持操作Personconverter之后把它支持的媒体类型统计出来。如此操作我们就得到了客户端支持接受的类型和服务端能够返回的类型,再通过内容协商的最佳匹配媒体类型,用支持将对象转为最佳匹配媒体类型converter

2 页面响应

  SpringBoot默认的打包方式是jar包方式,但是JSP不支持在jar包(一种压缩包)中编译,所以SpringBoot默认不支持JSP,于是我们需要引入第三方的模板引擎技术——Thymeleaf实现页面的渲染。

2.1 模板引擎之Thymeleaf

  要想使用Thymeleaf实现页面的渲染的话,首先需要在pom.xml文件里引入它的场景启动器依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

  在导入场景启动器之后,SpringBoot就会给我们在ThymeleafAutoConfiguration自动配置类中配置好所有的相关组件,并将相关配置项与ThymeleafProperties.class(代码如下)通过注解@EnableConfigurationProperties相关联,配置类中设置了默认页面跳转的前缀和后缀,也就是规范了页面存放的位置必须是templates文件夹和页面的文件后缀必须是.html,我们只需要直接开发页面即可。

private String prefix = "classpath:/templates/";
private String suffix = ".html";

入门案例

第一步: templates文件夹下建个html文件
第二步: <html>标签引入templates命名空间,这样的优点就是在进行页码编写的时候会有相关的提示信息

xmlns:th="http://www.thymeleaf.org"

第三步: 创建一个controller用于进页面跳转

@Controller
public class ViewTestController {@GetMapping("/jump")public String jumpTo(Model model) {// 之前讲过model的所有属性值都会存储在request域中,需要使用的时候直接使用model.addAttribute("msg", "你好,张三");model.addAttribute("link", "http://www.baidu.com");return "seccess";}
}

第四步: 编写页面代码获取域中的值

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1 th:text="${msg}">哈哈</h1><h2><a th:href="${link}">点击进入百度</a><a th:href="@{link}">点击进入百度</a></h2>
</body>
</html>  

在这里插入图片描述⚠  页面中两种符号区别:${}是直接获取到link属性的值作为链接地址,而@{}是拼装项目的访问路径+符号里的值,对本案例而言:第一个链接是打开百度,第二个是发送http://localhost:8080/link的请求

2.2 拦截器

  用户登陆成功之后,再发送任意请求的时候都应该是有个登录判断的过程(判断session中是否有正确的用户名和密码),这个功能可以在每个controller使用代码进行判断,但是这个过程是重复的会大大增加代码的冗余,于是我们可以将判断功能放在拦截器中,将登陆成功后的所有从页面发送的请求拦截住进行用户判断,成功则放行失败则返回登录。
  以上述例子为例讲解拦截器的使用:
第一步: 自定义拦截器(实现HandlerInterceptor接口,重写内置方法在相应的方法内编写判断逻辑)

public class LoginInterceptor implements HandlerInterceptor {// 在目标方法执行之前执行的方法@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 实现登录检查的逻辑HttpSession session = request.getSession();Object user = session.getAttribute("loginUser");if (user != null) {// 已经登录,放行return true;}// 未登录,重定向到登录页面request.setAttribute("msg", "请先登录之后再进行相关操作");request.getRequestDispatcher("/").forward(request, response);return false;}// 在目标方法执行之后执行的方法@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}// 页面渲染之后执行的方法@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

第二步: 自定义配置类实现WebMvcConfigurer接口,重写addInterceptors方法将拦截器注册进容器中,并指定拦截规则

@Configuration
public class AdminWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 有个问题就是,拦截器拦截的不只是动态请求,还有静态的页面资源和样式,所以也要将静态资源放行registry.addInterceptor(new LoginInterceptor())// 拦截所有的请求.addPathPatterns("/**")// 直接放行的请求.excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/js/**", "/images/**");}
}

2.3 文件上传

  文件上传需要前后端的协调配合,前端使用一个form表单提交所有的信息,包括单文件上传和多文件上传,后端使用注解获取到表单中的所有值,对他们进行操作
前端表单:

<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data"><!--email邮箱--><div class="form-group"><label for="exampleInputEmail1">Email address</label><input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"></div><!--userName用户名--><div class="form-group"><label for="exampleInputPassword1">userName</label><input type="text" name="userName" class="form-control" id="exampleInputPassword1" placeholder="Password"></div><!--单文件上传 头像--><div class="form-group"><label for="exampleInputFile">headerImg</label><input type="file" name="headerImg" id="exampleInputFile"></div><!--多文件上传 生活照--><div class="form-group"><label for="exampleInputFile">image of yourself</label><input type="file" name="photos" multiple ></div><div class="checkbox"><label><input type="checkbox"> Check me out</label></div><button type="submit" class="btn btn-primary">Submit</button>
</form>

后端controller:

@PostMapping("/upload")
public String upload(@RequestParam("email") String email,@RequestParam("userName") String userName,@RequestPart("headerImg")MultipartFile headerImg,@RequestPart("photos")MultipartFile[] photos) throws IOException {// 将头像保存到本地磁盘中if (!headerImg.isEmpty()) {// 创建相应的文件夹File file1 = new File("E:\\bootTest\\" + userName + "\\headerImg");file1.mkdirs();// 获取图片名 生成存储路径headerImg.transferTo(new File("E:\\bootTest\\" + userName + "\\headerImg\\" + headerImg.getOriginalFilename()));}// 将生活照保存到本地磁盘中if (photos.length > 0) {// 创建相应的文件夹File file1 = new File("E:\\bootTest\\" + userName + "\\photos");file1.mkdirs();// 存储图片for (MultipartFile photo:photos) {if (!photo.isEmpty()) {// 获取图片名 生成存储路径photo.transferTo(new File("E:\\bootTest\\" + userName + "\\photos\\" + photo.getOriginalFilename()));}}}return "index";
}

文件上传的配置:

# 文件上传大小的设置
spring:servlet:multipart:# 单个文件的最大大小max-file-size: 50MB# 总文件的最大大小max-request-size: 100MB

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

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

相关文章

2020年最快的dns_2020年哪里换旅行证最快取证?需要几天?

关注我的都知道了很多的实用攻略你还在等什么~美妈不论去哪个地方更换旅行证&#xff0c;都喜欢问“这个地方是否可以加急&#xff1f;”“最快几天可以拿到新的旅行证&#xff1f;”今天就来整理一下2020年各地换证需要几天&#xff0c;是否可以加急。"目前更换旅行证有两…

语句拼接_Linux 进阶语句

日常工作需要用到&#xff0c;shell语句用于分析定位生产问题&#xff0c;本次做个记录# 将日志先拷贝到当前目录cp /tmp/nginx.log .本次目标是&#xff1a; 找出log中的404 500的报错#使用管道取出相关日志less nginx.log 通过/ 查询得知 状态码处于第9个字段#使用 awk 筛选出…

【SpringBoot 2】(九)异常处理 web原生组件的注入

写在前面&#x1f6eb;更多知识总结见SpringBoot 2专栏 &#x1f695;本篇知识点总结自尚硅谷雷神的视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客首页&#x1f680;&#x1f680;…

项目管理最佳实践方法_项目管理最佳实践,企业如何进行有效的项目管理

前言&#xff1a;企业在划分项目时&#xff0c;可按照项目的复杂程度、管理范围等将项目分为三个级别&#xff0c;分别是企业级、部门级和小组级&#xff08;与目标划分原则相同&#xff09;&#xff0c;然后将每一级的目标与项目对应起来。我们知道&#xff0c;企业制定的目标…

python 历遍子弹_python之子弹移动

"""新增功能&#xff1a;完成我方坦克发射子弹的移动"""import pygameimport timeimport randomwin_width 700win_height 500bg_color pygame.Color(0, 0, 0)text_color pygame.Color(255, 0, 0)class MainGame():window Nonemy_tank None…

【SpringBoot 2】(十)数据库相关

写在前面&#x1f6eb;更多知识总结见SpringBoot 2专栏 &#x1f695;本篇知识点总结自尚硅谷雷神的视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客首页&#x1f680;&#x1f680;…

线性分组码的最小汉明距为6_第二章 线性代数

2.1 标量、向量、矩阵和张量标量(scalar)一个标量就是一个单独的数&#xff0c;用斜体表示标量。向量(vector)一个向量是一列有序排列的数&#xff0c;用粗写的小写字母表示。矩阵(matrix)矩阵式一个二维数组&#xff0c;其中的么一个元素由两个索引(而非一个)所确定&#xff0…

【SpringBoot 2】(十一)单元测试JUnit 5 指标监控

写在前面&#x1f6eb;更多知识总结见SpringBoot 2专栏 &#x1f695;本篇知识点总结自尚硅谷雷神的视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客首页&#x1f680;&#x1f680;…

sklearn中lstm_分别用sklearn和tensorflow做房价预测

原标题&#xff1a;分别用sklearn和tensorflow做房价预测本篇是后面用tensorflow做回归时的一个参照&#xff0c;忍不住要说的是sklearn真是简单好用&#xff0c;要不是他没有卷积cnn等时髦模型&#xff0c;真是不想用其他家的了。经典的sklearn集成模型结果&#xff1a;真是又…

多个containers 共用一个pvc_2020阜新PVC-UH市政管厂家-烟台塑胶

2020阜新PVC-UH市政管厂家烟台金沃泉塑胶有限公司主要产品PVC-U、PVC-M、PVC-UH聚氯乙烯给给水管材、HDPE高密度聚乙烯给水管材、CPVC氯化聚氯乙烯、MPP高压电力电缆护套管、PERT-Ⅱ型热力管道、高分子托辊管、水处理膜壳管。公司为电网、南方电网、电建集团、建筑集团、五矿集…

【SpringBoot 2】(十二) profile功能 自定义starter

写在前面&#x1f6eb;更多知识总结见SpringBoot 2专栏 &#x1f695;本篇知识点总结自尚硅谷雷神的视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客首页&#x1f680;&#x1f680;…

jpa transaction 回滚_我遇到的JPA中事务回滚的问题

在最近的项目中&#xff0c;做的是解析XML文件&#xff0c;解析过程中会有异常&#xff0c;比如&#xff1a;XML文件中节点的数据和与之对应的数据库的字段中数据的类型不匹配&#xff1b;XML中数据长度超过数据库定义的长度&#xff1b;有数据了的重复插入问题&#xff1b;读取…

pb 怎么判断是 小数_考试90分以上的孩子是怎么学数学的?听听老师怎么说?

一二年级&#xff0c;考试上九十分很轻松。但是&#xff0c;不少小朋友一上三年级&#xff0c;成绩就落下来了。那么&#xff0c;我们来看看三年级起&#xff0c;考试还能够保持在90分以上的孩子是怎么学习数学的吧&#xff01;第一&#xff0c;计算能力过关通过这两张图片的对…

快速上手Mybatis-Plus 入门案例

写在前面&#x1f6eb;更多知识总结见Mybatis-Plus专栏 &#x1f695;内容总结自尚硅谷杨博超老师的视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客首页&#x1f680;&#x1f680;…

交换机分布缓存_网络交换机缓存在数据中心的作用

什么产生了缓存&#xff1f;网络交换机要配置多少缓存才够用&#xff1f;缓存容量是否有标准可以衡量&#xff1f; 当网络交换机接口收到超出其所能处理的流量后&#xff0c;它会选择要么将其缓存&#xff0c;或者将其丢弃。 缓存通常都是因为网络接口速率不同造成的&#xff0…

黑苹果 选择语言 点不了_什么是天然的“黑钻”?—科普贴

天然黑钻也被成为“碳酸氢”&#xff0c;具有与白钻相同的化学成分&#xff0c;然而黑钻石的晶体结构是不同的&#xff0c;这意味着它们由许多小晶体组成&#xff0c;它们以随机的形式粘在一起&#xff0c;而不是一个具有可识别自然线的固体锥形。天然黑钻石有极高的含物&#…

sim卡没坏但苹果手机无服务_解决手机插SIM卡后都显示“无SIM卡”的故障问题

故障现象顾客描述手机插SIM卡后都显示“无SIM卡”。维修过程引起插入SIM卡却显示“无SIM卡”的故障&#xff0c;除了可能是SIM卡座的供电、时钟、复位及SIM卡插入检测信号不正常导致外&#xff0c;还有可能是基带不正常导致的。插上手机卡&#xff0c;左上角提示“无SIM卡”&am…

Mybatis-Plus实现简单的增删改查 实体类上的注解

写在前面&#x1f6eb;更多知识总结见Mybatis-Plus专栏 &#x1f695;内容总结自尚硅谷杨博超老师的视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客首页&#x1f680;&#x1f680;…

webpack 读取文件夹下的文件_webpack基本介绍及使用

1.什么是webpackwebpack是一个前端资源加载/打包工具。它根据模块的依赖关系进行静态分析&#xff0c;然后将这些模块按照指定的规则生成对应的静态资源。从上图看出&#xff0c;webpack可以将多种静态资源js&#xff0c;css&#xff0c;less转换成一个静态文件&#xff0c;减少…

conda失败说没有写权限_爱情中,为什么男生表白失败,女生还说可以继续做朋友,想过没有...

在爱情中&#xff0c;不是每个男生都是幸运的&#xff0c;也不是每次的表白都是如你所愿的。有成功总有失败&#xff0c;成功是喜悦的&#xff0c;但是失败却是痛苦的。不过有的时候男生和女生表白以后&#xff0c;女生对男生说了这样的一段&#xff0c;其实我希望以后我们还是…