二、SpringMVC接收数据(页面跳转控制、返回JSON数据、返回静态页面)

二、SpringMVC接收数据

1、访问路径设置@RequestMappering

1、内容

1、@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式(handler方法)关联起来,建立映射关系。

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

2、匹配方式

1、精确路径匹配

1、就是在@RequestMappeing注解中,直接指定URL地址。不用任何的通配符。进行精确定位

2、例子

@Controller
public class UserController {

    /**
     * 精准设置访问地址 /user/login
     */
    @RequestMapping(value = {"/user/login"})
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }

    /**
     * 精准设置访问地址 /user/register
     */
    @RequestMapping(value = {"/user/register"})
    @ResponseBody
    public String register(){
        System.out.println("UserController.register");
        return "register success!!";
    }
}

2、模糊路径匹配

1、在@RequestMapping注解指定 URL 地址时,通过使用通配符,匹配多个类似的地址

2、语法

单层匹配和多层匹配:
  /*:只能匹配URL地址中的一层,如果想准确匹配两层,那么就写“/*/*”以此类推。
  /**:可以匹配URL地址中的多层。
其中所谓的一层或多层是指一个URL地址字符串被“/”划分出来的各个层次
这个知识点虽然对于@RequestMapping注解来说实用性不大,但是将来配置拦截器的时候也遵循这个规则

3、例子

@Controller
public class ProductController {

    /**
     *  路径设置为 /product/*  
     *    /* 为单层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *    /product/a/a 不可以
     *  路径设置为 /product/** 
     *   /** 为任意层任意字符串  /product/a  /product/aaa 可以访问此handler  
     *   /product/a/a 也可以访问
     */
    @RequestMapping("/product/*")
    @ResponseBody
    public String show(){
        System.out.println("ProductController.show");
        return "product show!";
    }
}

3、类和方法级别区别

1、@RequestMapping可以设置在类、方法上

2、设置在类上

  • @RequestMapping 注解可以设置在控制器类上,用于映射整个控制器的通用请求路径。
  • 这样,如果控制器中的多个方法都需要映射同一请求路径,就不需要在每个方法上都添加映射路径。
  • 就是说可以在类上写一个公共的路径,然后这个类的方法上就不用写这个公共的路径了

3、设置在方法上

  • 注解也可以单独设置在控制器方法上,用于更细粒度地映射请求路径和处理方法。
  • 当多个方法处理同一个路径的不同操作时,可以使用方法级别的 @RequestMapping 注解进行更精细的映射。
  • 就是说:直接设置在方法上,就是精确路径匹配。

4、例子

//1.标记到handler方法
@RequestMapping("/user/login")
@RequestMapping("/user/register")
@RequestMapping("/user/logout")

//2.优化标记类+handler方法
//类上
@RequestMapping("/user")
//handler方法上
@RequestMapping("/login")
@RequestMapping("/register")
@RequestMapping("/logout")

4、附带请求方式的限制

1、就是HTTP协议的八种请求方式,SpringMVC进行了封装

2、如下类

public enum RequestMethod {
  GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}

3、默认情况下:@RequestMapping是八中请求方式都可以访问

4、我们可以指定,只访问哪种方式

  • 注意:如果没有满足请求方式,就会报405错误

5、例子

@Controller
public class UserController {

    /**
     * 精准设置访问地址 /user/login
     * method = RequestMethod.POST 可以指定单个或者多个请求方式!
     * 注意:违背请求方式会出现405异常!
     */
    @RequestMapping(value = {"/user/login"} , method = RequestMethod.POST)
    @ResponseBody
    public String login(){
        System.out.println("UserController.login");
        return "login success!!";
    }

    /**
     * 精准设置访问地址 /user/register
     */
    @RequestMapping(value = {"/user/register"},method = {RequestMethod.POST,RequestMethod.GET})
    @ResponseBody
    public String register(){
        System.out.println("UserController.register");
        return "register success!!";
    }

}

6、补充注解【进阶】

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
  • 以上几个注解只能在方法上使用
  • 是一种快捷方式,底层是一样的

7、如果出现了多个handle方法映射到同一个地址,就会出现错误。因为SpringMVC也不知道使用哪个

2、❗❗接收参数

1、常用两种格式

1、Param和json比较

1、参数编码

1、param:是ASCII码。如果遇到空格会转义

2、JSON:被编码为UTF-8

2、数据类型

1、param:字符串

2、JSON:复杂数据类型、数组、对象

3、嵌套性

1、param:没有嵌套,不支持

2、JSON:支持参数嵌套。可以传递更复杂的数据结构

4、可读性

1、param:是字符串,比JSON更容易、简单、易读

2、JSON:传递嵌套数据结构的时候更清晰易懂

5、参数顺序

1、param:没有顺序限制

2、JSON:因为是键值对性质传递,所以键值对是有序排列的

6、总结

1、param 类型的参数适用于单一的数据传递,而 JSON 类型的参数则更适用于更复杂的数据结构传递。

2、根据具体的业务需求,需要选择合适的参数类型。

3、在实际开发中,常见的做法是:在 GET 请求中采用 param 类型的参数,而在 POST 请求中采用 JSON 类型的参数传递。

2、param参数接收

1、直接接收

1、就是直接在URL后面写?xxx=xx&yy=yy

2、要求

  • 形参列表,填写对应名称的参数就行。 请求参数名【前端】 = 形参参数
  • 名称相同
  • 可以不传值,也不会报错

3、例子

/**
    * 直接接收值
    * 名要求形参列表,填写对应名称的参数就行。 请求参数名【前端】 = 形参参数
     * 1、名称相同
     * 2、可以不传递,也不会报错
    */
    @RequestMapping("data")
    @ResponseBody
    public String data(String name,int age){
        System.out.println("name = " + name+"age="+age);
        return "name = " + name+"age="+age;
    }

2、指定任意请求参数

1、就是说:指定任意的请求参数名,要求必须传递;要求不必传递 给与一个默认值

2、就需要用到这个注解:@RequestParam

3、使用场景

  • 指定绑定的请求参数名
  • 要求请求参数必须传递
  • 为请求参数提供默认值

4、@RequestParam用法

  • value:指定请求参数名,如果请求参数名和形参名一样,就可以不管
  • required :false:前端必须穿参数,默认是必须的,不传就会报400错误
  • defaulValue:当非必须传递false时,可以是设置默认值

5、例子

/**
     * 指定任意的请求参数名,要求必须传递;要求不必传递 给与一个默认值
     * @RequestParam用法:
     *              value:指定请求参数名,如果请求参数名和形参名一样,就可以不管
     *              required :false:前端必须穿参数,默认是必须的,不传就会报400错误
     *              defaulValue:当非必须传递false时,可以是设置默认值
     * @param username
     * @param age
     * @return
     */
    @ResponseBody
    @RequestMapping("data1")
    public String data1(@RequestParam(value = "account") String username,
                        @RequestParam(required = false,defaultValue = "1")int age){
        System.out.println("username = " + username+"age="+age);
        return "username = " + username+"age="+age;
    }

3、特殊值(一名多值)

1、就是一个名字,传递多个值过来。例如集合

2、如果是个集合就需要添加一个注解:@RequestParam。否则会报类型异常的错误

3、加了这个注解就会将集合add加入对应的字符串

4、例子

/**
     * 特殊值
     * 就是一名多值:使用一个集合来接收
     *  如果这个集合的形参不加@RequestParam的话,就会报错,类型异常
     *  加了这个注解就会将集合add加入对应的字符串
     *
     * @param hbs
     * @return
     */
    @ResponseBody
    @RequestMapping("data2")
    public String  data2(@RequestParam List<String >hbs){
        System.out.println("hbs = " + hbs);
        return "ok";
    }

4、实体类接收

1、就是通过实体类来接收前端传来的参数

2、这个用的最多,因为java用对象来接收前端参数,然后对应实体类,再插入数据库就会方便很多。

3、例子

//    使用实体对象来接收,这个最重要,主要是java用对象接收,然后对应实体类,再插入到数据库中
    @ResponseBody
    @RequestMapping("data3")
    public String data3(User user){
        System.out.println("user = " + user);
        return user.toString();
    }

3、路径参数接收

1、介绍

1、路径传递参数是一种在 URL 路径中传递参数的方式。在 RESTful 的 Web 应用程序中,经常使用路径传递参数来表示资源的唯一标识符或更复杂的表示方式。而 Spring MVC 框架提供了 @PathVariable 注解来处理路径传递参数。

2、就必须用到这个注解@PathVariable

3、 @PathVariable

  • 注解来处理路径传递参数。
  • 允许将 URL 中的占位符映射到控制器方法中的参数。

2、例子

//    动态设计路径    {}在形参列表获取传入的参数
//    接收路径参数 String account ,String password 接收param格式参数
//    必须使用@PathVariable
    @RequestMapping("{account}/{password}")
    public String login(@PathVariable("account") String username,@PathVariable String password){
        System.out.println("username = " + username +"password"+password);
        return "username = " + username +"password"+password;
    }

4、Json参数接收

1、介绍

1、前端传来的json格式值,java的API无法接收,就需要使用配置类和插件来辅助完成

  • java不支持json数据类型处理
  • 没有接送类型处理的工具(Jackson)

2、如何解决

  • 导入一个jackson依赖

  • 
      com.fasterxml.jackson.core
      jackson-databind
      2.15.0
    
  • springmvc handlerAdpater配置json转化器,配置类需要明确

  • 就是在配置类上加个这个,我们也就不需要去配置【经理】、【秘书】了

    @EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器

2、@EnableWebMvc注解说明

1、@EnableWebMvc注解效果等同于在 XML 配置中,可以使用 <mvc:annotation-driven> 元素!我们来解析<mvc:annotation-driven>对应的解析工作!

2、让我们来查看下<mvc:annotation-driven>具体的动作!

3、先查看这个标签\最终对应解析java类

image-20240116173710120

4、查看解析类里面的动作

image-20240116173731987

5、查看源码

class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {

  public static final String HANDLER_MAPPING_BEAN_NAME = RequestMappingHandlerMapping.class.getName();

  public static final String HANDLER_ADAPTER_BEAN_NAME = RequestMappingHandlerAdapter.class.getName();

  static {
    ClassLoader classLoader = AnnotationDrivenBeanDefinitionParser.class.getClassLoader();
    javaxValidationPresent = ClassUtils.isPresent("jakarta.validation.Validator", classLoader);
    romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);
    jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader);
    jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
            ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
    jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
    jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
    jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
    gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
  }

  @Override
  @Nullable
  public BeanDefinition parse(Element element, ParserContext context) {
    //handlerMapping加入到ioc容器
    readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);

    //添加jackson转化器
    addRequestBodyAdvice(handlerAdapterDef);
    addResponseBodyAdvice(handlerAdapterDef);

    //handlerAdapter加入到ioc容器
    readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
    return null;
  }

  //具体添加jackson转化对象方法
  protected void addRequestBodyAdvice(RootBeanDefinition beanDef) {
    if (jackson2Present) {
      beanDef.getPropertyValues().add("requestBodyAdvice",
          new RootBeanDefinition(JsonViewRequestBodyAdvice.class));
    }
  }

  protected void addResponseBodyAdvice(RootBeanDefinition beanDef) {
    if (jackson2Present) {
      beanDef.getPropertyValues().add("responseBodyAdvice",
          new RootBeanDefinition(JsonViewResponseBodyAdvice.class));
    }
  }

3、例子

1、实体类

package com.atgui.pojo;
import lombok.Data;
@Data
public class Person {

    private String name;
    private int age;
    private String sex;
}

2、pathController、也就是handler

package com.atgui.json;

import com.atgui.pojo.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("json")
@ResponseBody
public class JsonController {

    //    问题:遇到json——415不支持数据类型错误,java不支持json格式,json是前端的格式
//      解决:1、导入json处理的依赖,2、handlerAdapter配置json转换器
    @PostMapping("data")
    public String data(@RequestBody Person person){
        System.out.println("person = " + person);
        return  person.toString();
    }
}

3、使用postman去测试

image-20240116173909113

5、Cookie参数接收

1、@CookieValue注释

1、这个注释就是用来设置接收cookie的值

2、例子

package com.atgui.cookie;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody
@RequestMapping("cookie")
public class CookieController {

//    接收一个cookie
    @RequestMapping("data")
    public String data(@CookieValue(value = "cookieName") String value){
        System.out.println("value = " + value);
        return "cookieName:"+value;
    }

//    设置一个cookie
    @RequestMapping("save")
    public String save(HttpServletResponse httpServletResponse){
        Cookie cookie =
                new Cookie("cookieName","root");
        httpServletResponse.addCookie(cookie);
        return "success";
    }
}

6、请求头数据接收

1、@RequestHeader

1、这个和Cookie一样,只要记住这个注解,到时候会用j就行

2、例子

package com.atgui.header;

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

@Controller
@ResponseBody
@RequestMapping("header")
public class HeaderController {
    @RequestMapping("data")
    public String  header(@RequestHeader("Host") String host) {
        System.out.println("host = " + host);
        return "host = " + host;
    }
}

7、原生API对象操作

Method Arguments :: Spring Framework

1、就是直接可以写在handler中的原生API,也就是参数

2、支持以下控制器方法的参数【常用】

Controller method argument 控制器方法参数 Description
jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse 请求/响应对象
jakarta.servlet.http.HttpSession 强制存在会话。因此,这样的参数永远不会为 null
java.io.InputStream, java.io.Reader 用于访问由 Servlet API 公开的原始请求正文。
java.io.OutputStream, java.io.Writer 用于访问由 Servlet API 公开的原始响应正文。
@PathVariable 接收路径参数注解
@RequestParam 用于访问 Servlet 请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。
@RequestHeader 用于访问请求标头。标头值将转换为声明的方法参数类型。
@CookieValue 用于访问Cookie。Cookie 值将转换为声明的方法参数类型。
@RequestBody 用于访问 HTTP 请求正文。正文内容通过使用 HttpMessageConverter 实现转换为声明的方法参数类型。
java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap 共享域对象,并在视图呈现过程中向模板公开。
Errors, BindingResult 验证和数据绑定中的错误信息获取对象!

3、例子

/**
 * 如果想要获取请求或者响应对象,或者会话等,可以直接在形参列表传入,并且不分先后顺序!
 * 注意: 接收原生对象,并不影响参数接收!
 */
@GetMapping("api")
@ResponseBody
public String api(HttpSession session , HttpServletRequest request,
                  HttpServletResponse response){
    String method = request.getMethod();
    System.out.println("method = " + method);
    return "api";
}

8、共享域对象操作

1、属性(共享)域作用回顾

1、在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:

  • ServletContext
  • HttpSession
  • HttpServletRequest
  • PageContext

2、ServletContext 共享域

  • 可以在整个 Web 应用程序中共享数据,是最大的共享域
  • 一般可以用于保存整个 Web 应用程序的全局配置信息,以及所有用户都共享的数据
  • 保存的数据是线程安全的

3、HttpSession 共享域

  • 可以在同一用户发出的多个请求之间共享数据,但只能在同一个会话中使用。
  • 例如:可以将用户登录状态保存在 HttpSession 中,让用户在多个页面间保持登录状态。

4、HttpServletRequest 共享域

  • 可以在同一个请求的多个处理器方法之间共享数据
  • 例如:可以将请求的参数和属性存储在 HttpServletRequest 中,让处理器方法之间可以访问这些数据

5、PageContext 共享域

  • 在 JSP 页面Servlet 创建时自动创建的。
  • 它可以在 JSP 的各个作用域中共享数据,包括pageScope、requestScope、sessionScope、applicationScope 等作用域

6、作用:

  • 共享域的作用是提供了方便实用的方式在同一 Web 应用程序的多个组件之间传递数据,并且可以将数据保存在不同的共享域中,根据需要进行选择和使用。
  • 图解
  • image-20240116183703015

2、原生实现

1、直接在handler中写参数就行。和普通方法一样

public class ShareController {
    private ServletContext servletContext;

//    原生API
    public void data(HttpServletResponse response, HttpServletRequest request){
//        调用原生方法
    }
}

3、Request级别属性(共享)域

1、使用 Model 类型的形参
@RequestMapping("/attr/request/model")
@ResponseBody
public String testAttrRequestModel(

        // 在形参位置声明Model类型变量,用于存储模型数据
        Model model) {

    // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
    // 存入请求域这个动作也被称为暴露到请求域
    model.addAttribute("requestScopeMessageModel","i am very happy[model]");

    return "target";
}
2、使用 ModelMap 类型的形参
@RequestMapping("/attr/request/model/map")
@ResponseBody
public String testAttrRequestModelMap(

        // 在形参位置声明ModelMap类型变量,用于存储模型数据
        ModelMap modelMap) {

    // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
    // 存入请求域这个动作也被称为暴露到请求域
    modelMap.addAttribute("requestScopeMessageModelMap","i am very happy[model map]");

    return "target";
}
3、使用map类型的形参
@RequestMapping("/attr/request/map")
@ResponseBody
public String testAttrRequestMap(

        // 在形参位置声明Map类型变量,用于存储模型数据
        Map<String, Object> map) {

    // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
    // 存入请求域这个动作也被称为暴露到请求域
    map.put("requestScopeMessageMap", "i am very happy[map]");

    return "target";
}

4、使用ModelAndView对象

@RequestMapping("/attr/request/mav")
public ModelAndView testAttrByModelAndView() {

    // 1.创建ModelAndView对象
    ModelAndView modelAndView = new ModelAndView();
    // 2.存入模型数据
    modelAndView.addObject("requestScopeMessageMAV", "i am very happy[mav]");
    // 3.设置视图名称
    modelAndView.setViewName("target");

    return modelAndView;
}

4、Session级别属性(共享)域

1、例子

@RequestMapping("/attr/session")
@ResponseBody
public String testAttrSession(HttpSession session) {
    //直接对session对象操作,即对会话范围操作!
    return "target";
}

5、Application级别属性(共享)域

@Autowired
private ServletContext servletContext;

@RequestMapping("/attr/application")
@ResponseBody
public String attrApplication() {

    servletContext.setAttribute("appScopeMsg", "i am hungry...");

    return "target";
}

9、接收参数的总结

1、路径设置

  • @RequestMapper(value="地址",method = "请求方式") 类 | 方法
  • @GetMapping /@PostMapping 方法

2、接收参数【重点】

  • param

    • 直接接收:handler(类型 形参名) 形参名 = 请求参数名

    • 注解指定:handler(@RequestParam(name="请求参数") ,request= true, defaultValue ="默认值")

    • 一名多值: handler(@RequestParam List key)

    • 实体接收:handler(实体 对象) 对象的属性名 = 请求参数名

  • 路径参数

    • 设置动态路径和表示:{key}/info/{key}

    • 接收路径:handler(@PathVariable(动态路径key) 类型 形参名)

  • Json

    • 接收数据:handler(@RequestBody 实体类 对象)
    • 准备工作:
    • 导入jackson依赖
    • @EnableWebMvc:加入handlerMapping、handerAdapter给handlerAdapter配置json处理器

3、cookie接收

  • handler(@CookieValue("cookie的名字"))

4、请求偷接收

  • handler(@RequestHeader("cookie的名字"))

5、原生API获取

  • handler(HTTPServletRequest,request,session
  • ServletContext - > ioc -> 全局变量 @Autowired

6、共享域获取

  • 原生api方式就行
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇