SpringBoot2零基础到精通之数据与页面响应


Posted in Java/Android onMarch 22, 2022

1 数据响应

SpringBoot2零基础到精通之数据与页面响应

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

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注解。

SpringBoot2零基础到精通之数据与页面响应

1.2 数据响应之内容协商

内容协商: 服务器会根据客户端接收能力的不同,返回不同媒体类型的数据。

原理: 前端发送请求的时候请求头携带Accept字段,用于服务器声明自己(客户端)能够接收的数据类型。

处理流程: 首先判断当前响应头中是否已经有之前处理时缓存的媒体类型,如果没有的话就是第一次处理需要确定处理的媒体类型,通过Accept字段获取客户(PostMan、浏览器)支持接收的内容类型。经过遍历循环所有当前系统的MessageConverter看谁支持操作这个对象(Person),找到支持操作Person的converter之后把它支持的媒体类型统计出来。如此操作我们就得到了客户端支持接受的类型和服务端能够返回的类型,再通过内容协商的最佳匹配媒体类型,用支持将对象转为最佳匹配媒体类型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}" rel="external nofollow" >点击进入百度</a>
       <a th:href="@{link}" rel="external nofollow" >点击进入百度</a>
   </h2>
</body>
</html>

SpringBoot2零基础到精通之数据与页面响应

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

2.2 拦截器

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

public class LoginInterceptor implements HandlerInterceptor {
    // 在目标方法执行之前执行的方法
    @Override
    public 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;
    }

    // 在目标方法执行之后执行的方法
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    // 页面渲染之后执行的方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

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

@Configuration
public class AdminWebConfig implements WebMvcConfigurer {

    @Override
    public 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

到此这篇关于SpringBoot2零基础到精通之数据与页面响应的文章就介绍到这了,更多相关SpringBoot2 数据响应内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Java/Android 相关文章推荐
深入理解以DEBUG方式线程的底层运行原理
Jun 21 Java/Android
自从在 IDEA 中用了热部署神器 JRebel 之后,开发效率提升了 10(真棒)
Jun 26 Java/Android
解决ObjectMapper.convertValue() 遇到的一些问题
Jun 30 Java/Android
总结Java对象被序列化的两种方法
Jun 30 Java/Android
SpringBoot快速入门详解
Jul 21 Java/Android
java调用Restful接口的三种方法
Aug 23 Java/Android
Java使用Unsafe类的示例详解
Sep 25 Java/Android
RestTemplate如何通过HTTP Basic Auth认证示例说明
Mar 17 Java/Android
Java Lambda表达式常用的函数式接口
Apr 07 Java/Android
JavaWeb Servlet开发注册页面实例
Apr 11 Java/Android
java中为什么说子类的构造方法默认访问的是父类的无参构造方法
Apr 13 Java/Android
Android实现获取短信验证码并自动填充
May 21 Java/Android
MybatisPlus EntityWrapper如何自定义SQL
Mar 22 #Java/Android
SpringBoot2零基础到精通之数据库专项精讲
Mar 22 #Java/Android
Spring Bean是如何初始化的详解
Mar 22 #Java/Android
关于EntityWrapper的in用法
Mar 22 #Java/Android
SpringBoot2零基础到精通之异常处理与web原生组件注入
Mar 22 #Java/Android
Java字符串逆序方法详情
Mar 21 #Java/Android
剑指Offer之Java算法习题精讲二叉树的构造和遍历
You might like
Zend Guard一些常见问题解答
2008/09/11 PHP
php中解析带中文字符的url函数分享
2015/01/20 PHP
简单谈谈php中的unicode和utf8编码
2015/06/10 PHP
ThinkPHP路由详解
2015/07/27 PHP
PHP简单实现欧拉函数Euler功能示例
2017/11/06 PHP
用JS实现一个页面多个css样式实现
2008/05/29 Javascript
javascript控制frame,iframe的src属性代码
2009/12/31 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
2011/06/27 Javascript
Javascript中常见的校验如域名、手机、邮箱等等
2014/01/02 Javascript
用IE重起计算机或者关机的示例代码
2014/03/10 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
JsRender for index循环索引用法详解
2014/10/31 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
2015/08/25 Javascript
jQuery基于正则表达式的表单验证功能示例
2017/01/21 Javascript
详解原生js实现offset方法
2017/06/15 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
详解JS模块导入导出
2017/12/20 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
JavaScript实现仿Clock ISO时钟
2018/06/29 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
vue通过数据过滤实现表格合并
2020/11/30 Javascript
详解Vue.js 响应接口
2020/07/04 Javascript
Openlayers实现扩散的动态点(水纹效果)
2020/08/17 Javascript
node.js如何根据URL返回指定的图片详解
2020/10/21 Javascript
Python对两个有序列表进行合并和排序的例子
2014/06/13 Python
Python pandas RFM模型应用实例详解
2019/11/20 Python
JupyterNotebook 输出窗口的显示效果调整实现
2020/09/22 Python
python爬虫分布式获取数据的实例方法
2020/11/26 Python
基于CSS3 animation动画属性实现轮播图效果
2017/09/12 HTML / CSS
美国围栏公司:Walpole Outdoors
2019/11/19 全球购物
职业教育毕业生求职信
2013/11/09 职场文书
大门门卫岗位职责
2013/11/30 职场文书
投标诚信承诺书
2014/05/26 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书