最全面的SpringBoot教程(三)——SpringBoot Web开发

前端 0

前言

在这里插入图片描述

本文为SpringBoot Web开发相关内容介绍,下边将对静态资源管理(包括:静态资源访问静态资源前缀webjar首页支持),请求参数处理(包括:Rest风格参数注释),数据响应模板引擎(包括:Thymeleaf模板引擎基本语法thymeleaf使用),登录功能 + 拦截器异常处理等进行详尽介绍~

📌博主主页:小新要变强 的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)


目录

SpringBoot Web开发

  • 前言
  • 目录
  • 一、静态资源管理
    • 1️⃣静态资源访问
    • 2️⃣静态资源前缀
    • 3️⃣webjar
    • 4️⃣首页支持
  • 二、请求参数处理
    • 1️⃣Rest风格
    • 2️⃣参数注释
  • 三、数据响应
  • 四、模板引擎
    • 1️⃣Thymeleaf模板引擎
    • 2️⃣基本语法
    • 3️⃣thymeleaf使用
  • 五、登录功能 + 拦截器
  • 六、异常处理
  • 后记

在这里插入图片描述

一、静态资源管理

1️⃣静态资源访问

默认情况下,Spring Boot 从类路径中的/static (或/public 或/resources 或/META-INF/resources)目录或 ServletContext的根目录提供静态内容。

访问: 当前项目根路径/ + 静态资源名

原理: 静态映射/**。

请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

我们添加图片到resource下的static里:

在这里插入图片描述

请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

2️⃣静态资源前缀

可以添加访问静态资源前缘:

spring:  mvc:    static-path-pattern: /res/**

现在访问就是: 当前项目根路径 + /res + 静态资源名

3️⃣webjar

webjar官网:https://www.webjars.org/

webJars是可以让大家以jar包的形式来使用前端的各种框架、组件。例如,引用jquery。

<dependency>    <groupId>org.webjars</groupId>    <artifactId>jquery</artifactId>    <version>3.6.1</version></dependency>

在这里插入图片描述

访问路径:当前项目根路径/ + webjars/**

在这里插入图片描述

4️⃣首页支持

  • 静态资源路径下 index.html
  • 可以配置静态资源路径
  • 不能与静态资源前缀共用
spring:  resources:    static-locations: [classpath:/haha/]

二、请求参数处理

1️⃣Rest风格

RESTFUL是一种网络应用程序的设计风格和开发方式。

对比:

功能传统请求Rest风格
获取用户/user/getUser (GET请求)/user (GET请求)
保存用户/user/saveUse (POST请求)/user (POST请求)
修改用户/user/editUser (POST请求)/user (PUT请求)
删除用户/user/deleteUser(POST请求)/user (DELETE请求)

springboot用法:表单method=post,隐藏域 _method=put。

(1)开启页面表单的Rest功能

spring:  mvc:    hiddenmethod:      filter:        # 开启页面表单的Rest功能        enabled: true

(2)添加页面请求

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><script src="/webjars/jquery/3.6.1/jquery.js"></script><body>    <h1>首页</h1>    <button id="getUser">获取用户</button>    <button id="saveUser">保存用户</button>    <button id="editUser">修改用户</button>    <button id="deleteUser">删除用户</button>    <p id="msg"></p><script>    $("#getUser").on("click",()=>{        $.get("/user",(res)=>{            $("#msg").text(res);        })    });    $("#saveUser").on("click",()=>{        sendAjax(null);    });    $("#editUser").on("click",()=>{        sendAjax('PUT');    });    $("#deleteUser").on("click",()=>{        sendAjax("DELETE");    });    function sendAjax(type){        let data = {'_method':type}        $.post("/user",data,(res)=>{            $("#msg").text(res);        })    }</script></body></html>

(3)添加后端接口

// 组合注解,@Controller + RequestBody@RestController@RequestMapping("/user")public class UserController {    // 普通写法    // @RequestMapping(value = "/user",method = RequestMethod.GET)    // 精简写法    @GetMapping    public String getUser(){        return "get user";    }    @PostMapping    public String saveUser(){        return "post user";    }    @PutMapping    public String editUser(){        return "put user";    }    @DeleteMapping    public String deleteUser(){        return "delete user";    }}

为什么明明请求方式是POST,会跑到别的接口。

  • 核心Filter;HiddenHttpMethodFilter。
  • 由过滤器来判断改变。

在这里插入图片描述

如果请求方式是直接发送Put、delete等方式请求,无需Filter。

扩展:_method的值可以自定义,只需要重新实现过滤器方法即可。

//自定义filter@Beanpublic HiddenHttpMethodFilter hiddenHttpMethodFilter(){    HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();    methodFilter.setMethodParam("_m");    return methodFilter;}

2️⃣参数注释

  • @PathVariable:从请求路径上获取参数
  • @RequestHeader:从请求头上获取参数
  • @RequestParam:从请求参数上获取参数
  • @CookieValue:从请求Cookie中获取参数
  • @RequestBody:从请求body上获取参数
  • @MatrixVariable:从请求路径上;分割获取变量
    • SpringBoot默认禁用
    • 语法: 请求路径/test;user=jack;age=16,interests=sleep,dream
    • 后端接收,@MatrixVariable("user") String name,@MatrixVariable("age") Integer age,@MatrixVariable("interests") List<String> interests
@GetMapping("/{id}")public String getParam(@PathVariable("id") Integer id,                      @RequestHeader("Host") String host,                      @RequestParam("name") Integer name,                      @CookieValue("_username") String usernmae){}@PostMappingpublic void postMethod(@RequestBody String content){}// 可以传多个值,用对象来接收,存在相同属性时,会自动封装到里面。@PostMappingpublic void postMethod(@RequestBody Student student){}

三、数据响应

数据响应,一般分两个类型:

  • 响应页面
  • 响应数据

响应数据的格式可以是json,xml,io流等。

SpringMVC支持返回值:

ModelAndViewModelViewResponseEntity ResponseBodyEmitterStreamingResponseBodyHttpEntityHttpHeadersCallableDeferredResultListenableFutureCompletionStageWebAsyncTask@ModelAttribute 且为对象类型的@ResponseBody 注解

四、模板引擎

SpringBoot默认不支持 JSP,需要引入第三方模板引擎技术实现页面渲染。

1️⃣Thymeleaf模板引擎

官网:https://www.thymeleaf.org/

前端显示页面,是html页面。我们以前开发,做的是jsp页面,jsp可以动态渲染一些数据在页面上,可以写Java代码。JSP+Servlet+JavaBean,是我们很早之前就不用了,企业也用得少。

现在SpringBoot推荐Thymeleaf模板引擎。

2️⃣基本语法

表达式名字语法用途
变量取值${…}获取请求域、session域、对象等值
选择变量*{…}获取上下文对象值
消息#{…}获取国际化等值
链接@{…}生成链接
片段表达式~{…}jsp:include 作用,引入公共页面片段
<!-- 常用标签,一般都是  th:XXX --><!-- 需要设置头部(非标准HTML5 规范),也可以不设置 --><html xmlns:th="http://www.thymeleaf.org"><!-- 不设置头部的写法(符合HTML5规范) --><p data-th-text="${msg}">msg</p><!--设置文本--><p th:text="${msg}">提醒消息</p><!--设置文本--><a th:href="@{href}">超链接</a><!-- 设置属性值 --><input type="text" th:id="${student.id}" /><!-- 获取session --><p th:id="${#session.user}" />

3️⃣thymeleaf使用

(1)添加thymeleaf依赖

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

(2)创建文件,springboot帮我们配置好了,我们直接开发页面即可

在这里插入图片描述

// 接口@Controllerpublic class IndexController {    @GetMapping("/thymeleaf")    public String index(Model model) {        model.addAttribute("msg","hello thymeleaf");        model.addAttribute("link","www.baidu.com");        // 返回视图层        return "thymeleaf";    }}

在templates下新建thymeleaf.html:

<!doctype html><html><head>    <meta charset="UTF-8">    <meta name="viewport"          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>Document</title></head><body>    <h1 data-th-text="${msg}">提醒消息</h1>    <h2>        <a data-th-href="${link}">超连接</a>    </h2></body></html>

(3)效果

在这里插入图片描述

五、登录功能 + 拦截器

例子:访问项目,需要登录,如果没有登录就不能访问

🍀(1)添加登录页面:login.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>LOGIN</title>    <style>        * {            margin: 0;            padding: 0;        }        html {            height: 100%;        }        body {            height: 100%;        }        .container {            height: 100%;            background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);        }        .login-wrapper {            background-color: #fff;            width: 358px;            height: 588px;            border-radius: 15px;            padding: 0 50px;            position: relative;            left: 50%;            top: 50%;            transform: translate(-50%, -50%);        }        .header {            font-size: 38px;            font-weight: bold;            text-align: center;            line-height: 200px;        }        .input-item {            display: block;            width: 100%;            margin-bottom: 20px;            border: 0;            padding: 10px;            border-bottom: 1px solid rgb(128, 125, 125);            font-size: 15px;            outline: none;        }        .input-item:placeholder {            text-transform: uppercase;        }        .btn {            border: 0;            font-size: 20px;            text-align: center;            padding: 10px;            width: 100%;            margin-top: 40px;            background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);            color: #fff;        }        .msg {            color:red;            text-align: center;            line-height: 88px;        }        a {            text-decoration-line: none;            color: #abc1ee;        }    </style></head><body><div class="container">    <div class="login-wrapper">        <div class="header">Login</div>        <div class="form-wrapper">            <form data-th-action="@{/login}" method="post">                <input type="text" name="username" placeholder="username" class="input-item" /  >                <input type="password" name="password" placeholder="password" class="input-item" />                <input type="submit" class="btn" value="Login" />            </form>        </div>        <div class="msg" data-th-text="${msg}">            Don't have account?            <a href="#">Sign up</a>        </div>    </div></div></body></html>

🍀(2)添加登录接口

@Controllerpublic class LoginController {    @GetMapping("/")    public String index() {        // 返回视图层        return "/login/login";    }    @PostMapping("/login")    public String login(String username, String password, HttpSession session, Model model) {        if(StringUtils.hasLength(username) && "123456".equals(password)){            //把登陆成功的用户保存起来            session.setAttribute("loginUserName",username);            //登录成功重定向到 thymeleaf ;  重定向防止表单重复提交            return "redirect:/thymeleaf";        }else {            model.addAttribute("msg","账号密码错误");            //回到登录页面            return "/";        }    }}

🍀(3)添加拦截器

继承HandlerInterceptor 接口

@Slf4jpublic class LoginInterceptor implements HandlerInterceptor {    /**     * 目标方法执行之前     * @param request     * @param response     * @param handler     * @return     * @throws Exception     */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        // 请求路径 request.getRequestURI();        //登录检查逻辑        HttpSession session = request.getSession();        Object loginUser = session.getAttribute("loginUserName");        if(loginUser != null){            //放行            return true;        }        //拦截住。未登录。跳转到登录页        request.setAttribute("msg","请先登录");        // 跳转        request.getRequestDispatcher("/").forward(request,response);        return false;    }}

🍀(4)配置拦截器

@Configurationpublic class AdminWebConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LoginInterceptor())                // 所有请求都被拦截包括静态资源                .addPathPatterns("/**")                // 放行的请求                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");    }}

🍀(5)测试

在这里插入图片描述

六、异常处理

错误处理:

  • 默认情况下,Spring Boot提供/error处理所有错误的映射
  • 对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
  • 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息

在这里插入图片描述
在这里插入图片描述

SpringBoot也为我们提供了自定义错误页的功能。

自定义错误页的话可以在静态路径(如/static/)下的error目录。或放在模板目录(如 /templates/)下的error目录,都会被SpringBootz自动解析。

DefaultErrorAttributes:定义错误页面中可以包含哪些数据。

在这里插入图片描述


后记

在这里插入图片描述

👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~

也许您对下面的内容还感兴趣: