2022尚硅谷SSM框架跟学(七)Spring MVC基础二

news2024/9/23 13:24:08

2022尚硅谷SSM框架跟学 七 Spring MVC基础二

    • 4.SpringMVC获取请求参数
      • 4.1.通过ServletAPI获取
      • 4.2.通过控制器方法的形参获取请求参数
      • 4.3.@RequestParam
      • 4.4.@RequestHeader
      • 4.5.@CookieValue
      • 4.6.通过POJO获取请求参数
      • 4.7.解决获取请求参数的乱码问题
    • 5.域对象共享数据
      • 5.1.使用ServletAPI向request域对象共享数据
      • 5.2.使用ModelAndView向request域对象共享数据
      • 5.3.使用Model向request域对象共享数据
      • 5.4.使用map向request域对象共享数据
      • 5.5.使用ModelMap向request域对象共享数据
      • 5.6.Model、ModelMap、Map的关系
      • 5.7.向session域共享数据
      • 5.8.向application域共享数据
    • 6.SpringMVC的视图
      • 6.1.ThymeleafView
      • 6.2.转发视图(不常用)
      • 6.3.重定向视图
      • 6.4.视图控制器view-controller
    • 7.RESTful
      • 7.1.RESTful简介
        • (1).资源
        • (2).资源的表述
        • (3).状态转移
      • 7.2.RESTful的实现
        • (1).查询所有用户信息
        • (2).查询id = 1的用户信息
        • (3).添加用户信息
      • 7.3.HiddenHttpMethodFilter
        • (1).修改用户信息
        • (2).删除 id = 5的用户信息
        • (3).派生注解

4.SpringMVC获取请求参数

创建新的测试控制层TestParamController
在这里插入图片描述
修改index.html增加代码

<hr>
<form th:action="@{/param/servletAPI}" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录"><br/>
</form>

4.1.通过ServletAPI获取

将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象
修改TestParamController.java

package com.atguigu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName: TestParamController
 * @Description:
 * @Author: wty
 * @Date: 2023/1/29
 */
@Controller
public class TestParamController {
    @RequestMapping("/param/servletAPI")
    public String getParamByServletAPI(HttpServletRequest request) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username:" + username);
        System.out.println("password:" + password);
        return "success";
    }
}

重新部署Tomcat
在这里插入图片描述
输入账号和密码
在这里插入图片描述
点击登录后,成功跳转
在这里插入图片描述
看一下控制台的输出结果
在这里插入图片描述
总结
通过servletAPI获取:只需要在控制器方法的形参位置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数。

4.2.通过控制器方法的形参获取请求参数

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参。
修改index.html

<hr>
<form th:action="@{/param}" method="post">
    用户名:<input type="text" name="name"><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="登录"><br/>
</form>

修改TestParamController.java,新增方法

@RequestMapping("/param")
    public String getParamByParam(String name, String pwd) {
        System.out.println("name:" + name);
        System.out.println("pwd:" + pwd);
        return "success";
    }

重新部署Tomcat
在这里插入图片描述
输入用户名和密码后,成功跳转
在这里插入图片描述
看一下控制台输出的结果
在这里插入图片描述
总结
通过控制器方法的形参获取
只需要在控制器方法的形参位置,设置一个形参,形参的名字和请求参数的名字一致即可。

注:
若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串、数组或者字符串类型的形参接收此请求参数。
若使用字符串数组类型的形参,此参数的数组中包含了每一个数据。
若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果。

验证以上结论,我们看下,如果获取的参数名和实际参数名不一致会怎么样呢?
修改index.html,把name的n写成大写N
在这里插入图片描述
再重新部署一下Tomcat,输入账号和密码
在这里插入图片描述
跳转成功
在这里插入图片描述
看一下控制台的结果,用户名得到的是null
在这里插入图片描述

那我们就需要手动建立实际参数和指定参数之间的映射关系,需要引入注解@RequestParam

4.3.@RequestParam

修改TestParamController.java

    @RequestMapping("/param")
    public String getParamByParam(@RequestParam(value = "Name", required = true) String name, String pwd) {
        System.out.println("name:" + name);
        System.out.println("pwd:" + pwd);
        return "success";
    }

看一下RequestParam.class的源码,
可以发现required属性默认是true(必填)
在这里插入图片描述
重新部署Tomcat输入账号和密码
在这里插入图片描述
跳转成功
在这里插入图片描述

查看控制台的结果
在这里插入图片描述
那如果我们手动输入地址,没有放入Name这个required = true 的参数会发生什么呢?
跳转网址

http://localhost:8080/SpringMVC/param?Name=jackpassword=123

在这里插入图片描述
网站报错

HTTP Status 400 - Required String parameter ‘Name’ is not present

那如果我们加上Name呢
跳转网站

http://localhost:8080/SpringMVC/param?Name=jackpassword=123

跳转成功
在这里插入图片描述
修改TestParamController.java
required = false设置为不必填
defaultValue默认值设置为hello

    @RequestMapping("/param")
    public String getParamByParam(@RequestParam(value = "Name", required = false, defaultValue = "hello") String name, String pwd) {
        System.out.println("name:" + name);
        System.out.println("pwd:" + pwd);
        return "success";
    }

再次跳转网址看一下

http://localhost:8080/SpringMVC/param?password=123

成功跳转
在这里插入图片描述

控制台输出结果
在这里插入图片描述
可以看出来,如果跳转的网址没有加入参数Name,就会展示默认值。

总结
@RequestParam是将请求参数和控制器方法的形参创建映射关系
@RequestParam注解一共有三个属性:
value:指定为形参赋值的请求参数的参数名。
required:设置是否必须传输此请求参数,默认值为true
若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错

400:Required String parameter ‘xxx’ is not present;

若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null。
defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为""时,则使用默认值为形参赋值。

4.4.@RequestHeader

将请求头信息和控制器方法的形参绑定。
按F12,比如,现在想获取请求头中Referer这个参数的信息
在这里插入图片描述
这里就要引入注解@RequestHeader
先看一下RequestHeader.class的源码
在这里插入图片描述
修改TestParamController.java

    @RequestMapping("/param")
    public String getParamByParam(
            @RequestParam(value = "Name", required = false, defaultValue = "hello") String name,
            String pwd,
            @RequestHeader("Referer") String referer
    ) {
        System.out.println("name:" + name);
        System.out.println("pwd:" + pwd);
        System.out.println("referer:" + referer);
        return "success";
    }

重新部署Tomcat看一下
在这里插入图片描述
输入用户名和密码,跳转后查看参数Referer
在这里插入图片描述
查看控制台,输出没有问题
在这里插入图片描述
这里注意请求头首字母,大小写不区分,所以写成以下的小写形式也是可以的。

@RequestHeader("referer")

总结
@RequestHeader是将请求头信息和控制器方法的形参创建映射关系
@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam。

4.5.@CookieValue

将cookie数据和控制器方法的形参绑定。

先看一下源码CookieValue.class
在这里插入图片描述
修改TestParamController.java
在getParamByServletAPI方法中增加获取session
在getParamByParam方法中增加jsessionId

package com.atguigu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @ClassName: TestParamController
 * @Description:
 * @Author: wty
 * @Date: 2023/1/29
 */
@Controller
public class TestParamController {
    @RequestMapping("/param/servletAPI")
    public String getParamByServletAPI(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username:" + username);
        System.out.println("password:" + password);
        return "success";
    }

    @RequestMapping("/param")
    public String getParamByParam(
            @RequestParam(value = "Name", required = false, defaultValue = "hello") String name,
            String pwd,
            @RequestHeader("referer") String referer,
            @CookieValue("JSESSIONID") String jsessionId
    ) {
        System.out.println("name:" + name);
        System.out.println("pwd:" + pwd);
        System.out.println("referer:" + referer);
        System.out.println("jsessionId:" + jsessionId);
        return "success";
    }
}

重新部署Tomcat
在这里插入图片描述
产生JSESSIONID
在这里插入图片描述
之后再跑下面的功能
在这里插入图片描述
发现携带了cookie
在这里插入图片描述
看一下控制台
在这里插入图片描述
总结
@CookieValue是将cookie数据和控制器方法的形参创建映射关系
@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam。

4.6.通过POJO获取请求参数

创建新实体类User.java
在这里插入图片描述
代码如下:

package com.atguigu.pojo;

/**
 * @ClassName: User
 * @Description:
 * @Author: wty
 * @Date: 2023/1/29
 */

public class User {
    private Integer id;
    private String password;
    private String username;

    public User() {
    }

    public User(Integer id, String password, String username) {
        this.id = id;
        this.password = password;
        this.username = username;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", password='" + password + '\'' +
                ", username='" + username + '\'' +
                '}';
    }
}

修改index.html

<hr>
<form th:action="@{/param/pojo}" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录"><br/>
</form>

修改TestParamController.java增加新方法

    @RequestMapping("/param/pojo")
    public String getParamByPojo(User user) {
        System.out.println("user:" + user);
        return "success";
    }

重新部署Tomcat,输入账号和密码
在这里插入图片描述
跳转成功
在这里插入图片描述
控制台输出结果,把user的信息输出了
在这里插入图片描述
总结
可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值。

4.7.解决获取请求参数的乱码问题

先看一下乱码问题是怎么样的,登录的用户名输入中文
在这里插入图片描述
跳转结果
在这里插入图片描述
查看控制台,发现用户名是?
在这里插入图片描述
那我们把post请求更改成get会怎样呢
修改index.html

<form th:action="@{/param/pojo}" method="get">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录"><br/>
</form>

再重新部署一下Tomcat,看一下控制台的结果,发现竟然正常显示了
在这里插入图片描述
原因是Tomcat8之后的版本,都自动解决了get请求乱码的问题,而post请求乱码需要我们手动解决

修改web.xml,增加过滤器

   <!-- 配置spring的编码过滤器 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

看一下CharacterEncodingFilter的源码
encoding的设置
在这里插入图片描述
forceEncoding的设置
在这里插入图片描述
源码会设置请求和响应的编码
在这里插入图片描述
修改index.html,变更为post
在这里插入图片描述

输入用户名和密码
在这里插入图片描述
跳转成功
在这里插入图片描述

再看看控制台没有乱码了
在这里插入图片描述
总结
解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册

注:
SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效。

5.域对象共享数据

创建TestScopeController.java
在这里插入图片描述

5.1.使用ServletAPI向request域对象共享数据

在index.html中增加

<br/>
<a th:href="@{/ServletAPI}">使用ServletAPI向request域对象共享数据</a>

在TestScopeController.java中增加

@Controller
public class TestScopeController {
    @RequestMapping("/ServletAPI")
    public String testServletAPI(HttpServletRequest request) {
        request.setAttribute("testScope", "hello,servletAPI");
        return "success";
    }
}

在success.html中增加

<p th:text="${testScope}"></p>

点击超链接跳转
在这里插入图片描述
成功显示设置的共享数据
在这里插入图片描述

5.2.使用ModelAndView向request域对象共享数据

在index.html中增加

<a th:href="@{/test/mav}">使用ModelAndView向request域对象共享数据</a>

在TestScopeController.java中增加

 /**
     * ModelAndView有Model和View的功能
     * Model主要用于向请求域共享数据
     * View主要用于设置视图,实现页面跳转
     */
    @RequestMapping("/test/mav")
    public ModelAndView testMAV() {
        ModelAndView mav = new ModelAndView();
        //向请求域共享数据
        mav.addObject("testRequestScope", "hello,ModelAndView");
        //设置视图,实现页面跳转
        mav.setViewName("success");
        return mav;
    }

在success.html中增加

<p th:text="${testRequestScope}"></p><br/>

重新部署Tomcat
在这里插入图片描述
点击超链接之后,发现成功展示了共享数据
在这里插入图片描述
总结
通过ModelAndView向请求域共享数据
使用ModelAndView时,可以使用其Model功能向请求域共享数据,使用View功能设置逻辑视图,但是控制器方法一定要将ModelAndView作为方法的返回值。

5.3.使用Model向request域对象共享数据

在index.html中添加

<a th:href="@{/test/model}">使用Model向request域对象共享数据</a><br/>

在TestScopeController.java中添加代码

    @RequestMapping("/test/model")
    public String testModel(Model model) {
        model.addAttribute("testModel", "hi");
        return "success";
    }

修改success.html

<p th:text="${testModel}"></p><br/>

重新部署Tomcat
在这里插入图片描述
单击超链接跳转后,成功加载共享数据
在这里插入图片描述

5.4.使用map向request域对象共享数据

在index.html中增加

<a th:href="@{/test/map}">使用map向request域对象共享数据</a><br/>

在TestScopeController.java中增加

@RequestMapping("/test/map")
    public String testMap(Map<String, Object> map) {
        map.put("testMap", "hi,i am map");
        return "success";
    }

在success.html中增加

<p th:text="${testMap}"></p><br/>

重新部署Tomcat
在这里插入图片描述
单击超链接,发现成功展示共享数据
在这里插入图片描述

5.5.使用ModelMap向request域对象共享数据

在index.html中增加

<a th:href="@{/test/testModelMap}">使用ModelMap向request域对象共享数据</a><br/>

在TestScopeController.java中增加

    @RequestMapping("/test/testModelMap")
    public String testModelMap(ModelMap modelMap) {
        modelMap.addAttribute("modelMap", "hello,i am modelMap");
        return "success";
    }

在success.html中增加

<p th:text="${modelMap}"></p><br/>

重新部署Tomcat
在这里插入图片描述
点击超链接之后,成功跳转展示共享数据的内容
在这里插入图片描述

5.6.Model、ModelMap、Map的关系

我们修改TestScopeController.java,让其打印三者运行时类型
在testModel方法中增加

        System.out.println("model:" + model.getClass().getName());

发现打印控制台的结果
在这里插入图片描述

在testMap方法中增加

        System.out.println("map:" + map.getClass().getName());

发现打印控制台的结果
在这里插入图片描述

在testModelMap方法中增加

        System.out.println("modelMap:" + modelMap.getClass().getName());

发现打印控制台的结果
在这里插入图片描述
发现三者本质都是同一个类型

model:org.springframework.validation.support.BindingAwareModelMap

总结
Model、ModelMap、Map类型的参数其实本质上都是 BindingAwareModelMap 类型的

public interface Model{}
public class LinkedHashMap<K, V> extends HashMap<K, V> implements Map<K, V>
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {}

5.7.向session域共享数据

在index.html中添加

<a th:href="@{/test/testsession}">向session域共享数据</a><br/>

在TestScopeController.java中添加代码

    @RequestMapping("/test/testsession")
    public String testSession(HttpSession session) {
        session.setAttribute("testSession", "hello, session");
        return "success";
    }

在success.html中添加代码

<p th:text="${session.testSession}"></p><br/>

重新部署Tomcat得到
在这里插入图片描述
跳转后得到session域共享数据
在这里插入图片描述

5.8.向application域共享数据

在index.html中添加

<a th:href="@{/test/testapplication}">向application域共享数据</a><br/>

在TestScopeController.java中添加代码

    @RequestMapping("/test/testapplication")
    public String testapplication(HttpSession session) {
        ServletContext servletContext = session.getServletContext();
        servletContext.setAttribute("testApplication", "hello, application");
        return "success";
    }

在success.html中添加代码

<p th:text="${application.testApplication}"></p><br/>

重新部署Tomcat得到
在这里插入图片描述
单击超链接得到application域共享数据
在这里插入图片描述
这里看到同样展示了session作用域的数据,那是因为session作用域的范围是浏览器的,那么我们复制地址,关掉浏览器用其它浏览器重新再打开一次。我们选择主页

http://localhost:8080/SpringMVC/

然后单击map的超链接
在这里插入图片描述

发现session域和application的共享都没有了

在这里插入图片描述

那么我们想保留session的数据呢,很简单,我们设置Tomcat的配置,在保留session共享数据这里打勾即可。
在这里插入图片描述
设置完毕后我们重新部署Tomcat,
然后我们选择主页

http://localhost:8080/SpringMVC/

然后单击session的超链接
在这里插入图片描述
跳转后显示session的共享数据
在这里插入图片描述

然后单击application的超链接
在这里插入图片描述
跳转后显示application的共享数据
在这里插入图片描述

然后单击map的超链接
在这里插入图片描述

跳转后session、map、application都显示了
在这里插入图片描述
现在再重新部署Tomcat
刷新当前网址

http://localhost:8080/SpringMVC/test/map

发现session仍然存在,application没有了
在这里插入图片描述

6.SpringMVC的视图

SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户。
SpringMVC视图的种类很多,默认有转发视图重定向视图
当工程引入jstl的依赖,转发视图会自动转换为JstlView。
若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是ThymeleafView

比如,我们现在配置的springmvc.xml文件中配置的是ThymeleafViewResolver
在这里插入图片描述
在TestScopeController.java类中的testMAV方法的第一行打上断点,之后点击超链接跳转
在这里插入图片描述
进入断点后,找到Debugger中的DispatcherServlet打上断点,发现mv也是ModelAndView类型的。
在这里插入图片描述
同理在model共享数据域的方法testModel中打上断点,也是跳转到相同的代码。
在这里插入图片描述
跳转到DispatcherServlet的断点。
在这里插入图片描述
同样的,上一章讲述的所有共享数据域:
1.使用ServletAPI向request域对象共享数据
2.使用ModelAndView向request域对象共享数据
3.使用Model向request域对象共享数据
4.使用map向request域对象共享数据
5.使用ModelMap向request域对象共享数据
最终都是通过中央控制器DispatcherServlet类中的ModelAndView方式来共享数据的。

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

以map保存域为例,打个断点看一下mv的存储结果
在这里插入图片描述

6.1.ThymeleafView

修改index.html,增加代码

<hr>
<a th:href="@{/test/view/thymeleaf}">测试SpringMVC的视图ThymeleafView</a>

新建类TestViewController.java

package com.atguigu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @ClassName: TestViewController
 * @Description:
 * @Author: wty
 * @Date: 2023/1/30
 */
@Controller
public class TestViewController {
    @RequestMapping("/test/view/thymeleaf")
    public String testThymeleafView() {
        return "success";
    }
}

给testThymeleafView方法第一行打上断点
在这里插入图片描述
重新部署Tomcat然后点击超链接
在这里插入图片描述
进入断点
在这里插入图片描述
之后点击F7进入方法processDispatchResult,主要看视图渲染
在这里插入图片描述
按F7进入render方法,看到视图渲染的类型,是根据逻辑视图的名称来判断的,当前没有前缀,就是ThymeleafView
在这里插入图片描述
总结:
当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式实现跳转。

6.2.转发视图(不常用)

修改index.html,增加代码
注意,这种方式不常用,因为重新转发后的视图,不会经过Thymeleaf渲染,所以该方式不推荐

<a th:href="@{/test/view/forward}">测试SpringMVC的视图InternalResourceView</a><br/>

修改TestViewController.java增加方法

    @RequestMapping("/test/view/forward")
    public String testInternalResourceView() {
        return "forward:/test/model";
    }

重新部署Tomcat
在这里插入图片描述
点击跳转的超链接,进入断点
在这里插入图片描述
进入断点后,因为是服务器端的转发,那么会再进入一次断点,服务端转发后这次就是ThymeleafView视图,因为这次的视图名是success没有前缀。
在这里插入图片描述
最后的网址为
在这里插入图片描述

总结:
SpringMVC中默认的转发视图是InternalResourceView
SpringMVC中创建转发视图的情况:
当控制器方法中所设置的视图名称以"forward:"为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"forward:“去掉,剩余部
分作为最终路径通过转发的方式实现跳转,例如"forward:/”,"forward:/employee

6.3.重定向视图

修改index.html

<a th:href="@{/test/view/redirect}">测试SpringMVC的视图RedirectView</a><br/>

修改TestViewController.java

    @RequestMapping("/test/view/redirect")
    public String testRedirectView() {
        return "redirect:/test/model";
    }

重新部署Tomcat
在这里插入图片描述
点击超链接跳转,之后进入断点,进入断点后获取视图RedirectView
在这里插入图片描述
客户端重定向,会再进入一次断点,此时就是ThymeleafView视图,因为这次的视图名是success没有前缀。
在这里插入图片描述
最终的网站变为重定向后的地址
在这里插入图片描述

总结
SpringMVC中默认的重定向视图是RedirectView
当控制器方法中所设置的视图名称以"redirect:"为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"redirect:“去掉,剩余部分作为最
终路径通过重定向的方式实现跳,转例如"redirect:/”,“redirect:/employee”

注:
重定向视图在解析时,会先将redirect:前缀去掉,然后会判断剩余部分是否以/开头,若是则会自动拼接上下文路径。

6.4.视图控制器view-controller

当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示。

修改springmvc.xml

    <!--
        视图控制器view-controller
        仅仅用来实现页面跳转
        path:设置处理的请求地址
        view-name:设置请求地址所对应的视图名称
    -->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

注释掉PortalController.java中的跳转index界面的方法
在这里插入图片描述
重新部署Tomcat,发现仍然可以正常的跳转到首页
在这里插入图片描述
但是里面的超链接点击后,都会报错404

HTTP Status 404 -

在这里插入图片描述
这里的原因是,如果当SpringMVC中设置任何一个view-controller时,只有该设置会通过中央控制器来加载,而其他控制器中的请求映射将全部失效。解决办法就是加上注解驱动

修改springmvc.xml,加上代码

    <!-- 开启mvc的注解驱动 -->
    <mvc:annotation-driven/>

再次重新部署Tomcat,点击超链接,成功跳转
在这里插入图片描述

注:
当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动的标签:
< mvc:annotation-driven />

7.RESTful

7.1.RESTful简介

REST:Representational State Transfer,表现层资源状态转移。

(1).资源

资源是一种看待服务器的方式,即:将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。

(2).资源的表述

资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格
式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。

(3).状态转移

状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。

7.2.RESTful的实现

具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE用来删除资源。
REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。

操作传统方式REST风格
查询操作getUserById?id=1user/1–>get请求方式
保存操作saveUseruser–>post请求方式
删除操作deleteUser?id=1user/1–>delete请求方式
更新操作updateUseruser–>put请求方式

简单看一下REST风格,以百度百科为例,搜索RESTful
在这里插入图片描述
更换一下词条,发现前面一致,只是后面搜索的词条变了
在这里插入图片描述
创建一个新的工程

Name:spring-mvc-rest
GroupId:com.atguigu

在pom.xml中添加代码,增加打包方式

<packaging>war</packaging>

把之前helloworld中的pom.xml拷贝到到当前

<dependencies>
        <!-- SpringMVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.1</version>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- ServletAPI -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- Spring5和Thymeleaf整合包 -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.12.RELEASE</version>
        </dependency>
    </dependencies>

之后配置web.xml,配置路径如下:

F:\javawebwork\SSM\spring-mvc-rest\src\main\webapp\WEB-INF\web.xml

如图所示
在这里插入图片描述
之后在web.xml中增加代码

    <!-- 设置Spring的编码过滤器 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 设置springMVC的前端控制器 -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!-- 将前端控制器的启动时间提前到服务启动时 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

创建控制层TestRestController.java
在这里插入图片描述
创建配置文件springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 扫描控制层组件(自己配置package) -->
    <context:component-scan base-package="com.atguigu.controller"></context:component-scan>

    <!-- 配置Thymeleaf视图解析器(直接拷贝即可) -->
    <bean id="viewResolver"
          class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <!--
                            比如当前index的实际位置在/WEB-INF/templates/index.html(物理视图)
                            去掉视图前缀变为 index.html
                            去掉视图后缀变为 index(逻辑视图)
                        -->
                        <!-- 视图前缀 -->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <!-- 配置视图控制器 -->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

    <!-- 开启mvc注解驱动 -->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

</beans>

创建目录templates
在这里插入图片描述

(1).查询所有用户信息

在目录templates创建index.html作为首页

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/user}">查询所有的用户信息</a>

</body>
</html>

新建success.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>跳转成功</title>
</head>
<body>
<h1>success.html</h1>
</body>
</html>

在TestRestController.java中添加方法

package com.atguigu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@Controller
public class TestRestController {
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getAllUser() {
        System.out.println("查询操作 getAllUser user-->get请求方式");
        return "success";
    }
}

重新配置和部署Tomcat
在这里插入图片描述
设置Artifacts
在这里插入图片描述
配置启动参数
在这里插入图片描述
启动Tomcat,点击超链接
在这里插入图片描述
发现成功跳转
在这里插入图片描述

(2).查询id = 1的用户信息

修改index.html增加代码

<a th:href="@{/user/1}">查询id为1的用户信息</a><br>

修改TestRestController.java

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public String getUserById(@PathVariable("id") Integer id) {
        System.out.println("根据id查询用户信息操作 getUserById user/" + id + "-->get请求方式");
        return "success";
    }

部署Tomcat之后,点击超链接
在这里插入图片描述
发现成功跳转,并且地址加载出了1
在这里插入图片描述
再看下控制台,也获取到了1
在这里插入图片描述

(3).添加用户信息

修改index.html,因为是保存信息,是需要提交表单的,所以用了post请求。

<form th:action="@{/user}" method="post">
    <input type="submit" value="添加用户信息">
</form><br>

修改TestRestController.java

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String insertUser() {
        System.out.println("添加用户信息 insertUser user-->post请求方式");
        return "success";
    }

重新部署Tomcat,点击form表单的按钮
在这里插入图片描述
发现跳转成功
在这里插入图片描述
再看一下控制台的信息
在这里插入图片描述

7.3.HiddenHttpMethodFilter

(1).修改用户信息

修改index.html

<form th:action="@{/user}" method="put">
    <input type="submit" value="修改用户信息">
</form>
<br>

修改TestRestController.java

    @RequestMapping(value = "/user", method = RequestMethod.PUT)
    public String updateUser() {
        System.out.println("修改用户信息 updateUser user-->put请求方式");
        return "success";
    }

重新部署Tomcat
在这里插入图片描述
点击form表单的按钮,发现成功跳转但是地址有问号
在这里插入图片描述

再看一下控制台的信息,竟然匹配成了查询
在这里插入图片描述
这就说明了,当前浏览器的请求方式发送过来就是get,并不是我们写了put就变成了put,method只能写post和get
在这里插入图片描述
这个时候需要修改web.xml,增加过滤器
在这里插入图片描述
代码如下:

    <!-- 设置处理请求方法的过滤器 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

修改index.html
(1)修改method请求方式为post
(2)增加 name=“_method” 的input标签

<form th:action="@{/user}" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="修改用户信息">
</form>
<br>

这次我们再重新部署一下Tomcat,可以看到成功跳转
在这里插入图片描述
我们再看一下控制台,成功输出信息
在这里插入图片描述

(2).删除 id = 5的用户信息

修改index.html

<form th:action="@{/user/5}" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="删除用户信息">
</form>
<br>

修改TestRestController.java

    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    public String deleteUser(@PathVariable("id") Integer id) {
        System.out.println("删除用户信息 deleteUser user/" + id + "-->delete请求方式");
        return "success";
    }

重新部署Tomcat,点击删除的form表单
在这里插入图片描述
发现成功跳转
在这里插入图片描述

再看一下控制台的信息
在这里插入图片描述
总结
由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?
SpringMVC 提供了HiddenHttpMethodFilter帮助我们将 POST请求转换为DELETE或PUT请求
HiddenHttpMethodFilter处理put和delete请求的条件:

< a >.当前请求的请求方式必须为post
< b >.当前请求必须传输请求参数_method

满足以上条件,HiddenHttpMethodFilter过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此请求参数_method的值才是最终的请求方式。
在web.xml中注册HiddenHttpMethodFilter

<!-- 设置处理请求方法的过滤器 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

下面呢我们来看一下,这个过滤器的源码HiddenHttpMethodFilter.class
首先我们看到其继承类我们比较眼熟

public class HiddenHttpMethodFilter extends OncePerRequestFilter

想了想,编码过滤器CharacterEncodingFilter.class也继承自相同的类

public class CharacterEncodingFilter extends OncePerRequestFilter

打开alt+7我们查看源码的方法,过滤器选择这个即可。
在这里插入图片描述
查看源码
在这里插入图片描述
有参构造方法
在这里插入图片描述

注:
目前为止,SpringMVC中提供了两个过滤器:
CharacterEncodingFilterHiddenHttpMethodFilter
在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter。
原因:
在 CharacterEncodingFilter 中通过request.setCharacterEncoding(encoding) 方法设置字符集的request.setCharacterEncoding(encoding) 方法要求前面不能有任何获取请求参数的操作。
而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:

String paramValue = request.getParameter(this.methodParam);

(3).派生注解

最后我们用派生注解的方式来解决一下TestRestController.java
修改注解

    //@RequestMapping(value = "/user", method = RequestMethod.GET)
    @GetMapping("/user")

    //@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    @GetMapping("/user/{id}")

    //@RequestMapping(value = "/user", method = RequestMethod.POST)
    @PostMapping("/user")

    //@RequestMapping(value = "/user", method = RequestMethod.PUT)
    @PutMapping("/user")

    //@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    @DeleteMapping("/user/{id}")

这里贴一下全部代码方便查看

package com.atguigu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/**
 * @ClassName: TestRestController
 * @Description: 查询操作 getUserById?id=1 user/1-->get请求方式
 * 保存操作 saveUser user-->post请求方式
 * 删除操作 deleteUser?id=1 user/1-->delete请求方式
 * 更新操作 updateUser user-->put请求方式
 * @Author: wty
 * @Date: 2023/1/30
 */
@Controller
public class TestRestController {
    //@RequestMapping(value = "/user", method = RequestMethod.GET)
    @GetMapping("/user")
    public String getAllUser() {
        System.out.println("查询操作 getAllUser user-->get请求方式");
        return "success";
    }

    //@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    @GetMapping("/user/{id}")
    public String getUserById(@PathVariable("id") Integer id) {
        System.out.println("根据id查询用户信息操作 getUserById user/" + id + "-->get请求方式");
        return "success";
    }

    //@RequestMapping(value = "/user", method = RequestMethod.POST)
    @PostMapping("/user")
    public String insertUser() {
        System.out.println("添加用户信息 insertUser user-->post请求方式");
        return "success";
    }

    //@RequestMapping(value = "/user", method = RequestMethod.PUT)
    @PutMapping("/user")
    public String updateUser() {
        System.out.println("修改用户信息 updateUser user-->put请求方式");
        return "success";
    }

    //@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    @DeleteMapping("/user/{id}")
    public String deleteUser(@PathVariable("id") Integer id) {
        System.out.println("删除用户信息 deleteUser user/" + id + "-->delete请求方式");
        return "success";
    }
}

重新部署一下Tomcat
发现都可以正常执行,这就是派生注解的应用

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

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

相关文章

LCX端⼝转发

LCX是一款十分经典的内网端口转发工具&#xff0c;基于Socket套接字&#xff0c;具有端口转发和端口映射的功能。但是目前很多杀软已经将其加入了特征库&#xff0c;在实际利用的时候需要自行做免杀处理。lcx有三个功能&#xff1a;第一个功能将本地端口转发到本地另一个端口上…

红米10A 一键root教程 跳过 秒过 168小时解锁BL 限制完美面具root保数据救黑砖刷机 解决无法解锁BL 新版本问题

新版本红米10A 无法秒解锁BL。root bootloader 要刷机、线刷救砖、获取Root权限都需要解除bootloader锁 我们称解除刷机限制的这个操作就叫解锁BL&#xff0c;只有解锁BL后&#xff0c;才可以进行刷机、刷Root权限等等一些列的操作。&#xff08;注&#xff1a;bootloader锁不…

Spring为什么这么火 之 五大类注解

目录 前言 存储Bean对象 1、配置扫描路径 2、将Bean存储到容器中 2.1、5大注解实现&#xff08;Controller、Service、Repository、Component、Configuration) Controller Service Repository Configuration Component 为什么需要五个类注解&#xff1f; 五大类注解的关…

Jmeter分布式

Jmeter的分布式控制&#xff0c;就是指远程启动功能。执行原理&#xff1a; 1、一台作为调度机(master)&#xff0c;其它机器做为执行机(slave) 2、执行时&#xff0c;master会把脚本发送到每台slave上&#xff0c;slave 拿到脚本后就开始执行 3、执行完成后&#xff0c;sla…

go语言编译文件踩坑

目录 1 no required module provides package xxx go.mod file not found in current directory or any parent directory; see go help modules 方式1 执行 go env -w GO111MODULEauto后再编译 方式2 创建go.mod 2 报错syscall.go:84:16: undefined: unsafe.Slice 3 b…

ArrayList集合类和对象数组案例区别讲解

目录 对象数组案例讲解 集合 ArrayList类的构造方法和成员方法 对象数组案例讲解 创建一个学生数组&#xff0c;存储三个学生对象并遍历 package com.demo01; /*** * author 无限嚣张菜菜* 分析&#xff1a;* A&#xff1a;定义学生类* B&#xff1a;创建学生数组* C&am…

关于PKI 你了解多少

公钥基础设施PKI&#xff08;Public Key Infrastructure&#xff09;&#xff0c;是利用公开密钥机制建立起来的基础设施&#xff0c;在信息互联互通时代&#xff0c;可以说它是创建、颁发、管理、注销公钥证书所涉及的所有软件、硬件集合体。对拥有庞大用户的系统来说&#xf…

Activity的5种启动模式详解(新增singleInstancePerTask类型)

前言 看到这个标题的时候&#xff0c;也许你会认为我写错了&#xff0c;Activity不是只有四种启动模式吗&#xff1f;分别为startard,singleTop,singleTask,singleInstance这四种。 一般来说是四种&#xff0c;但是android12的时候新加入了singleInstancePerTask类型&#xf…

【金三银四系列】之MySql面试突击(2023版)

Mysql金三银四面试突击班 1.Bin log是什么&#xff0c;有什么用&#xff1f;&#xff08;数据库被人干掉了怎么办&#xff1f;&#xff09; 1.bin Log: 数据恢复 主从复制 MySQL Server 层也有一个日志文件&#xff0c;叫做 binlog&#xff0c;它可以被所有的存储引擎使用。…

PRD-产品需求说明文档

产品需求说明文档&#xff08;PRD&#xff09;可以将产品设计思路清晰的展现给团队人员&#xff0c;便于他们快速理解产品。产品需求说明文档如何写呢&#xff1f;本文希望能够得到高人指点&#xff0c;本人是小白&#xff0c;同时不建议其他小白参考此文以免造成干扰。 包括文…

Spark 学习案例

案例1&#xff1a;搜索引擎日志分析 数据来源&#xff1a;使用搜狗实验室提供的【用户查询日志】数据。使用Saprk框架&#xff0c;将数据封装到RDD中进行数据处理分析。 数据网址&#xff1a;数据地址 这个地址可能过期了&#xff0c;需要的伙伴可以私聊博主。 数据格式&…

css清除浮动的方法

浮动的盒子会脱离标准流&#xff0c;不占有自己原先的位置&#xff0c;导致下面的其他标签往上移动 此时&#xff0c;可以给浮动的盒子添加一个父盒子&#xff08;块级&#xff09;&#xff0c;并设置高度&#xff0c;就可以避免下面的其他标签上浮 但是有时候父盒子不能设置高…

pycharm:新建虚拟环境和安装依赖

前言 小编深有体会&#xff0c;在刚开始用pycharm跑python的项目的时候&#xff0c;一时间不知道如何下手&#xff0c;特别是作为一个新手小白&#xff0c;这里总结了一份新手避坑指南&#xff0c;主要是新建虚拟环境&#xff08;生成一个项目对应的解释器&#xff09;以及安装…

温度预测 python | 使用 Python 可以使用机器学习模型进行温度预测

使用 Python 可以使用机器学习模型进行温度预测。常用的模型有回归分析、随机森林等。使用前需要准备足够的历史数据并进行特征工程&#xff0c;构建模型并进行训练&#xff0c;最后使用预测结果。 文章目录温度预测 回归分析导入必要的库&#xff1a;读取温度数据&#xff1a;…

Java中的插入排序和希尔排序

插入排序&&希尔排序插入排序希尔排序上一篇博客我给大家伙说了一下子堆排序,之所以我把插入排序和希尔排序放在一起呢,是因为希尔排序实际上用到了插入排序的思想,希望下面的内容能够帮助到大家.对于插入排序呢,我们可以参考抓牌顺牌,就在一般情况下,我们也不考虑什么组…

对象在Eden区分配

一、对象在Eden区分配大多数情况下&#xff0c;对象在新生代中 Eden 区分配。当 Eden 区没有足够空间进行分配时&#xff0c;虚拟机将发起一次Minor GC。在测试之前我们先来看看 Minor GC和Full GC 有什么不同呢&#xff1f;Minor GC/Young GC&#xff1a;指发生新生代的的垃圾…

oracle11g SAP测试机归档日志暴增排查(二)

接上面一的内容&#xff0c;通过logminer可以知道是因为oracle11g设置awr快照引起的插入数据&#xff0c;所以要看这个插入是否正常。 之前也发现SYSAUX表空间也没有多少了&#xff0c;应该这个原因引起产生大量的日志 6、查找SYSAUX表空间满的原因 对于SYSAUX表空间而言&…

【博学谷学习记录】大数据课程-学习第五周总结

Hadoop概述 Hadoop介绍 Hadoop是Apache旗下的一个用java语言实现开源软件框架&#xff0c;是一个开发和运行处理大规模数据的软件平台。允许使用简单的编程模型在大量计算机集群上对大型数据集进行分布式处理。 狭义上说&#xff0c;Hadoop指Apache这款开源框架&#xff0c;它…

Gateway, Zuul, Oauth2.0, 前后端分离, 定制页面,登录回调接口的处理

由于公司与Alexa平台接入了语音控制的功能&#xff0c;需要将公司的账号与Alexa的账号进行绑定&#xff0c;所以需要账号授权的操作&#xff0c;也就是使用授权码模式。开发过程中遇到了很多坑&#xff0c;网上关于前后端分离的定制页面的介绍又很少&#xff0c;前前后后花了一…

泰拉瑞亚灾厄NPC不复活x哥布林军队入侵中断

文章首发及后续更新&#xff1a;https://mwhls.top/4415.html&#xff0c;无图/无目录/格式错误/更多相关请至首发页查看。 新的更新内容请到mwhls.top查看。 欢迎提出任何疑问及批评&#xff0c;非常感谢&#xff01; 目录 NPC 不复活 原因 解决办法 哥布林军队入侵中断 说…