2.0SpringMVC中@RequestMapping注解的使用 和 获取请求参数 和 域对象共享数据

文章目录

😹 作者: gh-xiaohe
😻 gh-xiaohe的博客
😽 觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!!

🚏 @RequestMapping注解

当前的请求 没有和任何一个@RequestMapping 的value 404

请求方式信息不对(method) 405

请求参数信息不对(params) 400

请求头信息不对(headers) 404

🚀 1、@RequestMapping注解的功能

从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。

SpringMVC接收到指定的请求,就会来找到在映射关系中对应的控制器方法处理这个请求

在这里插入图片描述

🚄 2、@RequestMapping注解的位置

@RequestMapping标识一个:设置映射请求的请求路径的初始信息

@RequestMapping标识一个方法:设置映射请求请求路径的具体信息

@Controller
@RequestMapping("/test")
public class RequestMappingController {

	//此时请求映射所映射的请求的请求路径为:/test/testRequestMapping
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        return "success";
    }

}

🚒 3、@RequestMapping注解的value属性

@RequestMapping注解的value属性通过请求的请求地址匹配请求映射

@RequestMapping注解的value属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求

@RequestMapping注解的value属性必须设置,至少通过请求地址匹配请求映射

<a th:href="@{/testRequestMapping}">测试@RequestMapping的value属性-->/testRequestMapping</a><br>
<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>
@RequestMapping(
        value = {"/testRequestMapping", "/test"}
)
public String testRequestMapping(){
    return "success";
}

🚤 4、@RequestMapping注解的method属性

不设置method属性就是不以method属性为条件,不以请求方式为条件

@RequestMapping注解的method属性通过请求的请求方式(get或post)匹配请求映射

@RequestMapping注解的method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配多种请求方式的请求

若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错405:Request method ‘POST’ not supported

<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>
<form th:action="@{/test}" method="post">
    <input type="submit">
</form>
@RequestMapping(
        value = {"/testRequestMapping", "/test"},
        method = {RequestMethod.GET, RequestMethod.POST}
)
public String testRequestMapping(){
    return "success";
}

注:

1、对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解

    处理get请求的映射–>@GetMapping --> 查询
    处理post请求的映射–>@PostMapping --> 添加

    处理put请求的映射–>@PutMapping --> 修改

    处理delete请求的映射–>@DeleteMapping --> 删除

2、常用的请求方式有get,post,put,delete

    但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理

    若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到

🚬 get 和 post 请求的区别

    get请求每当我们请求我们提交请求参数,请求参数就会拼接在请求地址后面,以?问号进行拼接 后面是 请求参数名 = 请求参数值 and 请求参数名 = 请求参数值 … (name = value)

         username=admin&password=123456

    post 会把请求参数放在请求体中,(get请求没有请求体) 格式:依旧还是 请求参数名 = 请求参数值

    get 请求相对来说不是很安全,post安全

    get的传输速度快(伴随着传输地址),post传输速度慢

    get的传输量有限,post的传输量比较大(可以认为是无限值) 文件上传是不能使用get

🚗 5、@RequestMapping注解的params属性(了解)

@RequestMapping注解的params属性通过请求的请求参数匹配请求映射

@RequestMapping注解的params属性是一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系

“param”:要求请求映射所匹配的请求必须携带param请求参数

“!param”:要求请求映射所匹配的请求必须不能携带param请求参数

“param=value”:要求请求映射所匹配的请求必须携带param请求参数且param=value

“param!=value”:要求请求映射所匹配的请求必须携带param请求参数但是param!=value

写法一:   idea 页面会报错(但是不影响)
<a th:href="@{/test?username=admin">测试@RequestMapping的params属性-->/test</a><br>
写法二:
<a th:href="@{/test(username='admin',password=123456)">测试@RequestMapping的params属性-->/test</a><br>
@RequestMapping(
        value = {"/testRequestMapping", "/test"}
        ,method = {RequestMethod.GET, RequestMethod.POST}
        ,params = {"username","password!=123456"}
)
public String testRequestMapping(){
    return "success";
}

注:

    若当前请求满足@RequestMapping注解的value和method属性,但是不满足params属性,此时页面回报错400:Parameter conditions “username, password!=123456” not met for actual request parameters: username={admin}, password={123456}

🚲 6、@RequestMapping注解的headers属性(了解)

@RequestMapping注解的headers属性通过请求的请求头信息匹配请求映射

@RequestMapping注解的headers属性是一个字符串类型的数组,可以通过四种表达式设置请求头信息和请求映射的匹配关系

“header”:要求请求映射所匹配的请求必须携带header请求头信息

“!header”:要求请求映射所匹配的请求必须不能携带header请求头信息

“header=value”:要求请求映射所匹配的请求必须携带header请求头信息且header=value

“header!=value”:要求请求映射所匹配的请求必须携带header请求头信息且header!=value

若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到

7、8同样说的也是value属性

🚛 7、SpringMVC支持ant风格的路径(模糊匹配的功能)

@RequeMapping中的value中存在 ? 、*、**

?:表示任意的单个字符 (必须有一个任意字符)

*:表示任意的0个或多个字符

**:表示任意的一层或多层目录 (注意不能在====的前后添加内容,如果添加的话就表示两个

注意:在使用**时,只能使用/**/xxx的方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0FCrRcg-1655035894354)(SpringMVC中@RequestMapping注解的使用.assets/image-20220612191244923.png)]

🚔 8、SpringMVC支持路径中的占位符(重点)RESTful 中使用

原始方式:/deleteUser?id=1
    
rest方式:/deleteUser/1

    SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在=通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参(获取占位符中的值也比较单一 只能通过@PathVariable注解获取

<a th:href="@{/testRest/1/admin}">测试路径中的占位符-->/testRest</a><br>
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id") String id, @PathVariable("username") String username){
    System.out.println("id:"+id+",username:"+username);
    return "success";
}
//最终输出的内容为-->id:1,username:admin

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F6dWy5G5-1655035894355)(SpringMVC中@RequestMapping注解的使用.assets/image-20220612195028578.png)]

🚏 SpringMVC获取请求参数

控制器方法是由谁调用的?

  • ①从浏览器发送的请求 会被@RequestMapping这个注解进行匹配

  • ②匹配成功,就会由当前的控制器方法来处理请求

  • ③浏览器发送的请求都要被前端控制处理 之后又执行相对应的控制方法

  • ④将我们的请求 和 @Requestmapping 进行匹配 来找到控制方法的过程 是由前端控制DispatcherServlet来完成

  • ⑤DispatcherServlet来调用(间接调用)控制器方法

  • ⑥过程是在DispatcherServlet中执行的

  • ⑦如何来执行的 请求地址 + @RequestMapping

  • ⑧在DispatcherServlet 封装了很多数据 当我们去调用我们的控制器方法时,就会根据 我们当前控制方法的参数 来为当前的方法 注入这个参数 (也就是为参数赋值)

🚀 1、通过ServletAPI获取 (很少使用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZu3gsma-1655382374370)(SpringMVC获取请求参数.assets/image-20220612221030127.png)]

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

@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username:"+username+",password:"+password);
    return "success";
}

🚄 2、通过控制器方法的形参获取请求参数

要求:形参的参数名,必须和请求参数的参数名一致

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

<a th:href="@{/testParam(username='admin',password=123456)}">测试获取请求参数-->/testParam</a><br>
@RequestMapping("/testParam")
public String testParam(String username, String password){
    System.out.println("username:"+username+",password:"+password);
    return "success";
}

注:

     若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9rDPOFOe-1655382374371)(SpringMVC获取请求参数.assets/image-20220613211157736.png)]

     若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
    
     若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果

@RequestParam、@RequestHeader、@CookieValue三者作用一样

🚒 3、@RequestParam

形参的参数名,请求参数的参数名不一致

@RequestParam是将请求参数控制器方法的形参创建映射关系

@RequestParam注解一共有三个属性:

     value:指定为形参赋值的请求参数的参数名

     required:设置是否必须传输此请求参数,默认值为true

     若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,并且没有设置defaultValue属性,则页面报错400:Required String parameter ‘xxx’ is not present;若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null

    defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为"" 时,则使用默认值为形参赋值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ktW77Pii-1655382374371)(SpringMVC获取请求参数.assets/image-20220613211924238.png)]

🚤 4、@RequestHeader

@RequestHeader是将请求头信息控制器方法的形参创建映射关系

@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TFN4TmyY-1655382374372)(SpringMVC获取请求参数.assets/image-20220613213941276.png)]

🚗 5、@CookieValue

    复习:Session 依赖于 Cookie ,Cookie 客户端的会话技术,Session 是服务器端的会话技术,Cookie 会话技术(默认:生命周期浏览器开启到浏览器关闭)

  @CookieValue是将cookie数据控制器方法的形参创建映射关系

  @CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

     ①第一次访问getSession方法,Cookie应该存在与响应报文
    
    ②第一次执行getSession方法时,会先检测一下 请求报文中是否会携带 J-SESSIONID-Cookie的id,没有的话说明是第一次访问,创建Session对象
    
    ③创建一个HttpSession对象Session放在服务器所维护的Map集合并且去创建一个Cookie,Cookie的是固定的J-SESSIONID是一个随机序列
    
    ④将我们当前的HttpSession对象存储我们当前的服务器维护的Map集合中(JSESSIONID随机生成的序列化,当做Map集合的键,Session对象当做Map集合的值)进行存储,存储到服务器的内部
    
    ⑤在把Cookie响应到浏览器
    在这里插入图片描述
    

    ⑥之后在进行访问时Cookie存在于请求报文中请求携带Cookie
    
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tMnFaFou-1655382374372)(SpringMVC获取请求参数.assets/image-20220613220624444.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W3XE7sp4-1655382374373)(SpringMVC获取请求参数.assets/image-20220613220833277.png)]

🚲 6、通过POJO(实体类)获取请求参数

    可以在控制器方法形参位置设置一个实体类类型形参,此时若浏览器传输的请求参数的参数名实体类中的属性名一致,那么请求参数就会为此属性赋值

public class User {

    private Integer id;

    private String username;

    private String password;

    private Integer age;

    private String sex;

    private String email;

    //get set 有参无参构造器 toString方法
}
<form th:action="@{/testpojo}" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    性别:<input type="radio" name="sex" value=""><input type="radio" name="sex" value=""><br>
    年龄:<input type="text" name="age"><br>
    邮箱:<input type="text" name="email"><br>
    <input type="submit">
</form>
@RequestMapping("/testpojo")
public String testPOJO(User user){
    System.out.println(user);
    return "success";
}
//最终结果-->User{id=null, username='张三', password='123', age=23, sex='男', email='123@qq.com'}

🛹 7、解决获取请求参数的乱码问题

    设置请求编码的前提条件:如果在此之前已将获取了某一个请求参数,所设置的编码没有效果

    解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册

乱码分为两种:

  •     get请求的乱码:get请求的乱码是由tomcat造成的(server.xml)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18wqpQ5f-1655382374373)(SpringMVC获取请求参数.assets/image-20220615212444657.png)]

  •     post请求的乱码
    <!--配置springMVC的编码过滤器-->
    <!--一定要配置到其他过滤器之前,否则无效-->
    <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>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

注:

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

🚏 域对象共享数据

    将请求参数作为条件,调用service处理业务逻辑,service调用dao来访问数据库,将最终的结果返回service,service返回给控制层,此时有数据是需要像页面发送,就需要将这些数据在域对象共享

🌟 域对象有四种(小到大)

根据有作用范围由小到大:

  • page(jsp有效)------》page域指的是pageContext.

  • request(一次请求)—》request域request HttpServletContext

  • session(一次会话)—》session域session HttpSession

  • application(当前web应用)—》application域指的是application ServletContext;

之所以他们是域对象,原因是他们都内置了map集合,都有setAttribute和getAttribute方法。

🚬 一、PageContext域(jsp有效)

🚭 生命周期:当对JSP的请求开始,当相应结束时销毁。
  • jsp页面被执行,声明周期开始;
  • jsp页面执行完毕,声明周期结束;
🚭 作用范围:整个JSP页面,是四大作用域中最小的一个。
🚭 作用:
  1. 获取其它八大隐式对象,可以认为是一个入口对象。
  2. 获取其所有域中的数据

🚬 二、Request域(常用)

🚭 生命周期:
  • Service方法调用前由服务器创建,传入service方法。整个请求结束,request生命结束。
  • 用户发送一个请求,开始,服务器返回响应,请求结束,生命周期结束;
🚭 作用范围:整个请求链(请求转发也存在)
🚭 作用:

    在整个请求链中共享数据,经常用到:在servlet中处理好的数据交给JSP显示,此时参数就可以放在Request域中。

🚬 三、HttpSession 域(常用)

🚭 生命周期:

    在第一次调用request.getSession()方法时,服务器会检查是否已经有对应的session,如果没有就在内存中创建一个session并返回

  • 当一段时间内session没有被使用(默认为30分钟),则服务器会销毁该session
  • 如果服务器非正常关闭,没有到期的session也会跟着销毁。
  • 如果调用session提供的invalidate(),可以立即销毁session

    用户打开浏览器访问,创建session(开始),session超时或者被声明失效,该对象生命周期结束;

🚭 作用范围:一次会话。

HttpSession 在服务器中,为浏览器创建独一无二的内存空间,在其中保存会话相关的信息

    注意:服务器正常关闭,再启动,Session对象会进行钝化和活化操作。同时如果服务器钝化的时间在session 默认销毁时间之内, 则活化后session还是存在的。否则Session不存在。 如果JavaBean 数据在session钝化时,没有实现Serializable 则当Session活化时,会消失

🚭 Session的工作原理图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rj93wN8j-1655601988969)(域对象共享数据.assets/image-20220618093903725.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dcrjb80t-1655601988971)(域对象共享数据.assets/image-20220618094034847.png)]

🚬 四、ServletContext

🚭 生命周期:
  • 当WEB应用被加载进容器创建代表整个WEB应用的ServletContext对象;
  • 当服务器关闭或WEB应用被移除时,ServletContext对象跟着被销毁。
🚭 作用范围:整个WEB应用。

1 - 6 都是想request域中进行数据共享

🚀 1、使用ServletAPI向request域对象共享数据

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LG6OregO-1655601988971)(域对象共享数据.assets/image-20220618102126209.png)]

🚄 2、使用ModelAndView向request域对象共享数据

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

🚒 3、使用Model向request域对象共享数据

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

🚤 4、使用map向request域对象共享数据

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
    map.put("testScope", "hello,Map");
    return "success";
}

🚗 5、使用ModelMap向request域对象共享数据

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

    控制器方法不一样,键是一样的,但是返回的值是不同的

🚲 6、Model、ModelMap、Map的关系

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

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

🚬 源码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PrRGQkfC-1655601988972)(域对象共享数据.assets/image-20220618214105677.png)]	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h5MFcZ30-1655601988972)(域对象共享数据.assets/image-20220618214123957.png)]
在这里插入图片描述

    五种方式都要把数据疯转到ModelAndView

在这里插入图片描述

🛹 7、向session域共享数据

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

index.html  <a th:href="@{/testApplication}">通过servletAPI向application域对象共享数据</a><br>

success.html<p th:text="${session.testSessionScope}"></p>

🚬 原生

@RequestMapping("/testSession")
public String testSession(HttpServletRequest request){
    request.getSession().setAttribute("testSessionScope", "hello,session");
    return "success";
}

🛴 8、向application域共享数据

@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
	ServletContext application = session.getServletContext();
    application.setAttribute("testApplicationScope", "hello,application");
    return "success";
}
index.html  <a th:href="@{/testSession}">通过servletAPI向session域对象共享数据</a><br>

success.html<p th:text="${application.testApplicationScope}"></p>
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gh-xiaohe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值