SpringMVC ——(1)

1.SpringMVC请求流程

1.1 SpringMVC请求处理流程分析

Spring MVC框架也是⼀个基于请求驱动的Web框架,并且使⽤了前端控制器模式(是⽤来提供⼀个集中的请求处理机制,所有的请求都将由⼀个单⼀的处理程序处理来进⾏设计,再根据请求映射规则分发给相应的⻚⾯控制器(动作/处理器)进⾏处理。⾸先让我们整体看⼀下Spring MVC处理请求的流程:

1.⾸先⽤户发送请求,请求被SpringMvc前端控制器(DispatherServlet)捕获;

2.前端控制器(DispatherServlet)对请求URL解析获取请求URI,根据URI, 调⽤HandlerMapping;

3.前端控制器(DispatherServlet)获得返回的HandlerExecutionChain(包括Handler对象以及Handler对象对应的拦截器);

4.DispatcherServlet 根据获得的HandlerExecutionChain,选择⼀个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter 后,此时将开始执⾏拦截器的preHandler(...)⽅法);

5.HandlerAdapter根据请求的Handler适配并执⾏对应的Handler;HandlerAdapter(提取Request中的模型数据,填充Handler⼊参,开 始执⾏Handler(Controller)。 在填充Handler的⼊参过程中,根据配置,Spring将做⼀些额外的工作:

HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成⼀个对象,将对象转换为指定的响应信息。

数据转换:对请求消息进⾏数据转换。如String转换成Integer、Double等数据格式化:

数据格式化。 如将字符串转换成格式化数字或格式化⽇期等

数据验证: 验证数据的有效性(⻓度、格式等),验证结果存储到BindingResult或Error中)

6.Handler执⾏完毕,返回⼀个ModelAndView(即模型和视图)给HandlerAdaptor

7.HandlerAdaptor适配器将执⾏结果ModelAndView返回给前端控制器。

8.前端控制器接收到ModelAndView后,请求对应的视图解析器。

9.视图解析器解析ModelAndView后返回对应View;

10.渲染视图并返回渲染后的视图给前端控制器。

11.最终前端控制器将渲染后的⻚⾯响应给⽤户或客户端

2.SpringMVC环境搭建

2.1开发环境

Idea + Maven + Jdk1.8 + Jetty

2.2. 新建 Maven webApp

Idea 下创建 springmvc01 ⼯程

2.3 pom.xml

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
​
  <dependencies>
    <!-- spring web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.4.RELEASE</version>
    </dependency>
    <!-- spring mvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.4.RELEASE</version>
    </dependency>
    <!-- web servlet -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
    </dependency>
  </dependencies>
  
  <build>
    <finalName>SpringMVC1</finalName>
​
    <plugins>
      <!-- 编译环境插件 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <!-- jetty插件 -->
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.4.27.v20200227</version>
        <configuration>
          <scanIntervalSeconds>10</scanIntervalSeconds>
          <!-- 设置端⼝ -->
          <httpConnector>
            <port>8080</port>
          </httpConnector>
          <!-- 设置项⽬路径 -->
          <webAppConfig>
            <contextPath>/springmvc01</contextPath>
          </webAppConfig>
        </configuration>
      </plugin>
    </plugins>
  </build>

2.4 配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
​
    <!-- 编码过滤 utf-8 -->
    <filter>
        <description>char encoding filter</description>
        <filter-name>encodingFilter</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>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- servlet请求分发器 -->
    <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:servlet-context.xml</param-value>
        </init-param>
        <!-- 表示启动容器时初始化该Servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <!-- 这是拦截请求, "/"代表拦截所有请求,"*.do"拦截所有.do请求 -->
        <!-- <url-pattern>/</url-pattern> -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>
2.4.1 servlet-context.xml配置
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
 http://www.springframework.org/schema/mvc
 http://www.springframework.org/schema/mvc/spring-mvc.xsd
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd">
​
    <!-- 开启扫描器 -->
    <context:component-scan base-package="org.example.springmvc.controller"/>
    <!-- 使⽤默认的 Servlet 来响应静态⽂件 -->
    <mvc:default-servlet-handler/>
    <!-- 开启注解驱动-->
    <mvc:annotation-driven/>
    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀:在WEB-INF⽬录下的jsp⽬录下 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀:以.jsp结尾的资源 -->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
2.4.2 页面控制器的编写
package org.example.springmvc.controller;
​
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
​
@Controller
public class HelloController {
​
    /**
     * 请求映射地址 /hello.do
     * @return
     */
    @RequestMapping("/hello")
    public ModelAndView hello(){
        ModelAndView mv=new ModelAndView();
        mv.addObject("hello", "hello spring mvc");
        mv.setViewName("hello");
        return mv;
    }
}
2.4.3 添加视图页面

在 WEB-INF 下新建 jsp ⽂件夹 ,并在⽂件夹下新建 hello.jsp

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath =
            request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"
            ;
%>
<!DOCTYPE HTML>
<html>
<head>
    <base href="<%=basePath %>">
    <title>My JSP 'hello.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
</head>
<body>
<!-- el表达式接收参数值 -->
${hello}
</body>
</html>
2.4.4 启动jetty服务器

2.4.5 页面结果

访问地址 http://localhost:8080/springmvc01/hello.do

3.URL地址映射配置

3.1 @RequestMapping

* URL地址映射配置
* @RequestMappping("路径")
* 注解可以声明在类级别或方法级别。如果注解设置在类级别,则表示将请求路径与控制器绑定;如果将注解设置在方法级别,则表示请求路径与方法绑定
* 1.类级别
* 2.方法级别
* 3.类级别+方法级别
*      注:如果在类上设置了@RequestMapping注解,则访问时需要将类路径当做方法路径的父路径。即 类路径/方法路径
3.1.1 映射单个URL

@RequestMapping("") 或 @RequestMapping(value="")

    /**
     * @RequestMapping 声明在⽅法上⾯,映射单个 URL
     * 访问地址:(如果有类路径需要写在⽅法路径前⾯)
     * http://ip:port/springmvc01/test01
     * @return
     */
    @RequestMapping("/test01")
// @RequestMapping(value = "/test01")
    public ModelAndView test01(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("hello","test01");
        modelAndView.setViewName("hello");
        return modelAndView;
    }
    /**
     * 路径开头是否加 斜杠"/" 均可
     * @RequestMapping("/请求路径") 与 @RequestMapping("请求路径")均可
     * 建议加上,如:@RequestMapping("/test02")
     * 访问地址:(如果有类路径需要写在⽅法路径前⾯)
     * http://ip:port/springmvc01/test02
     * @return
     */
    @RequestMapping("test02")
    public ModelAndView test02(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("hello","test02");
        modelAndView.setViewName("hello");
        return modelAndView;
    }
3.1.2 映射多个URL

@RequestMapping({"",""}) 或 @RequestMapping(value={"",""})

    /**
     * @RequestMapping 声明在⽅法上⾯,映射多个 URL
     * ⽀持⼀个⽅法绑定多个 url 的操作
     * 访问地址:(如果有类路径需要写在⽅法路径前⾯)
     * http://ip:port/springmvc01/test03_01
     * http://ip:port/springmvc01/test03_02
     * @return
     */
    @RequestMapping({"/test03_01","/test03_02"})
// @RequestMapping(value = {"/test03_01","/test03_02"})
    public ModelAndView test03() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("hello", "test03");
        modelAndView.setViewName("hello");
        return modelAndView;
    }
3.1.3 映射URL在控制器上
@Controller
@RequestMapping("/url")
public class UrlController {
    /**
    * @RequestMapping 声明在类上⾯,类中的的⽅法都是以该地址作为⽗路径
    * 声明级别:
     * 类级别 + ⽅法级别 (/类路径/⽅法路径)
     * 访问地址:
     * http://ip:port/springmvc01/url/test04
     * @return
    */
     @RequestMapping("/test04")
     public ModelAndView test04(){
         ModelAndView modelAndView = new ModelAndView();
         modelAndView.addObject("hello","test04");
         modelAndView.setViewName("hello");
         return modelAndView;
     }
}
3.1.4 设置URL映射的请求方式
/**
 * 设置请求⽅式
 * 通过 method 属性设置⽅法⽀持的请求⽅式,默认 GET请求和 POST等请求都⽀持。
 * 设置了请求⽅式,则只能按照指定的请求⽅式请求。
 * 访问地址:(只能使⽤POST请求访问)
 * http://ip:port/springmvc01/url/test05
 * @return
 */
@RequestMapping(value = "/test05",method = RequestMethod.POST)
public ModelAndView test05(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test05");
     modelAndView.setViewName("hello");
     return modelAndView;
}
3.1.5 通过参数名称映射URL
/**
 * 通过参数名称访问
 * 通过参数的形式访问
 * 访问地址:
 * http://ip:port/springmvc01/url?test06
 * @return
 */
@RequestMapping(params = "test06")
public ModelAndView test06(){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("hello","test06");
    modelAndView.setViewName("hello");
    return modelAndView;
}

4.参数绑定

4.1 基本数据类型

访问地址:http://localhost:8080/springmvc01/data01?age=18&money=500 (问号后面为参数)

/**
 * 基本类型数据绑定
 * 参数值必须存在。如果没有指定参数值,也没有设置参数默认值,则会报500异常。
 * @param age
 * @param money
 */
@RequestMapping("data01")
public void data01(int age, double money){
    System.out.println("age:" + age + ", money:" + money);
}
/**
 * 基本类型数据绑定
 * 通过注解 @RequestParam 标记⼀个形参为请求参数。(注解声明在形参的前⾯)
 * 可以通过注解的属性设置相关内容
 * 设置参数的默认值 defaultValue
 * @param age
 * @param money
 */
@RequestMapping("data02")
public void data02(@RequestParam(defaultValue = "18") int age,
@RequestParam(defaultValue = "10.0") double money){
    System.out.println("age:" + age + ", money:" + money);
}
​
/**
 * 基本类型数据绑定
 * 通过注解 @RequestParam 标记⼀个形参为请求参数。(注解声明在形参的前⾯)
 * 可以通过注解的属性设置相关内容
 * 设置参数的参数名(别名) name
 * @param age
 * @param money
 */
@RequestMapping("data03")
public void data03(@RequestParam(defaultValue = "18", name = "userAge") int age,
@RequestParam(defaultValue = "10.0", name = "userMoney") double money){
    System.out.println("age:" + age + ", money:" + money);
}

4.2 包装类型

/**
 * 包装类型数据绑定 (如果数据是基本类型,建议使⽤包装类型)
 * 客户端请求参数名与⽅法形参名保持⼀致,默认参数值为null
 * 可以通过 @RequestParam 的name属性设置参数的别名,defaultValue属性设置参数默认值
 * @param age
 * @param money
 */
@RequestMapping("data05")
public void data05(Integer age, Double money){
    System.out.println("age:" + age + ", money:" + money);
}

4.3 字符串类型

/**
 * 字符串数据绑定
 * 客户端请求参数名与⽅法形参名保持⼀致,默认参数值为null
 * 可以通过 @RequestParam 的name属性设置参数的别名,defaultValue属性设置参数默认值
 * @param userName
 * @param userPwd
 */
@RequestMapping("data04")
public void data04(String userName, String userPwd){
    System.out.println("userName:" + userName + ", userPwd:" + userPwd);
}

4.4 数组类型

/**
 * 数组类型数据绑定
 * 客户端传参形式:ids=1&ids=2&ids=3
 * @param ids
 */
@RequestMapping("/data06")
public void data06(String[] ids){
    for(String id : ids){
        System.out.println(id + "---");
    }
}

4.5 JavaBean类型

/**
 * JavaBean 数据绑定
 * 客户端请求的参数名与JavaBean对象的属性字段名保持⼀致
 * @param user
 */
@RequestMapping("/data07")
public void data07(User user) {
    System.out.println(user);
}

User.java

package com.xxxx.springmvc.po;
public class User {
 
    private int id;
    private String userName;
    private String userPwd;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + "]";
    }
}

4.6 List类型

此时 User 实体需要定义对应 list 属性。(对于集合的参数绑定,⼀般需要使⽤ JavaBean 对象进⾏包装)

public class User {
 
    private int id;
    private String userName;
    private String userPwd;
​
    private List<Phone> phones = new ArrayList<Phone>();
 
    public List<Phone> getPhones() {
        return phones;
    }
    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", phones=" + phones + "]";
    }
}

Phone实体

public class Phone {
 
    private String num;
    public String getNum() {
        return num;
    }
    public void setNum(String num) {
        this.num = num;
    }
    @Override
    public String toString() {
        return "Phone [num=" + num + "]";
    }
 
}

Jsp ⻚⾯定义

<form action="data08" method="post">
    <input name="phones[0].num" value="123456" />
    <input name="phones[1].num" value="4576" />
    <button type="submit"> 提交</button>
</form>

Controller ⽅法

@RequestMapping("/data08")
public void data08(User user){
    System.out.println(user);
}

4.7 Set类型

Set 和 List 类似,也需要绑定在对象上,⽽不能直接写在 Controller ⽅法的参数中。但是,绑定Set数

据时,必须先在Set对象中add相应的数量的模型对象。

public class User {
    private int id;
    private String userName;
    private String userPwd;
​
    private Set<Phone> phones = new HashSet<Phone>();
​
​
    public User() {
        phones.add(new Phone());
        phones.add(new Phone());
        phones.add(new Phone());
    }
    /*public List<Phone> getPhones() {
        return phones;
    }
    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }*/
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
    public Set<Phone> getPhones() {
        return phones;
    }
    public void setPhones(Set<Phone> phones) {
        this.phones = phones;
    }
}

Controller ⽅法

@RequestMapping("/data09")
public void data09(User user){
    System.out.println(user);
}

表单⻚⾯

<form action="data09" method="post">
    <input name="phones[0].num" value="123456" />
    <input name="phones[1].num" value="4576" />
    <input name="phones[2].num" value="4576" />
    <button type="submit"> 提交</button>
</form>

4.8 Map类型

Map最为灵活,它也需要绑定在对象上,⽽不能直接写在Controller⽅法的参数中。

public class User {
    private int id;
    private String userName;
    private String userPwd;
​
    private Set<Phone> phones=new HashSet<Phone>();
​
    private Map<String, Phone> map=new HashMap<String, Phone>();
​
    // private List<Phone> phones=new ArrayList<Phone>();
​
​
    public User() {
        phones.add(new Phone());
        phones.add(new Phone());
        phones.add(new Phone());
    }
    /*public List<Phone> getPhones() {
        return phones;
    }
    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }*/
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
    public Set<Phone> getPhones() {
        return phones;
    }
    public void setPhones(Set<Phone> phones) {
        this.phones = phones;
    }
    public Map<String, Phone> getMap() {
        return map;
    }
    public void setMap(Map<String, Phone> map) {
        this.map = map;
    }
}

Controller ⽅法

@RequestMapping("/data10")
public void data10(User user){
    Set<Entry<String, Phone>> set = user.getMap().entrySet();
    for(Entry<String, Phone> entry:set){
        System.out.println(entry.getKey()+"--"+entry.getValue().getNum());
    } 
}

表单页面

<form action="data10" method="post">
    <input name="map['1'].num" value="123456" />
    <input name="map['2'].num" value="4576" />
    <input name="map['3'].num" value="4576" />
    <button type="submit"> 提交</button>
</form

5.请求转发与重定向

SpringMVC默认采⽤服务器内部转发的形式展示⻚⾯信息。同样也⽀持重定向⻚⾯。

5.1 重定向

重定向是发⼀个302的状态码给浏览器,浏览器⾃⼰去请求跳转的⽹⻚。地址栏会发⽣改变。

重定向以 redirect: 开头

/**
 * 重定向到JSP⻚⾯
 * @return
 */
@RequestMapping(value="/view01")
public String view01(){
    return "redirect:view.jsp";
}
/**
 * 重定向到JSP⻚⾯
 * 传递参数
 * @return
 */
@RequestMapping(value="/view02")
public String view02(){
    return "redirect:view.jsp?uname=zhangsan&upwd=123456";
}
/**
 * 重定向到JSP⻚⾯
 * 传递参数 (传递中⽂参数会出现乱码)
 * @return
 */
@RequestMapping(value="/view03")
public String view03(){
    return "redirect:view.jsp?uname=张三&upwd=123456";
}
/**
 * 重定向到JSP⻚⾯
 * 传递参数 (通过 RedirectAttributes 对象设置重定向参数,避免中⽂乱码问题)
 * @param redirectAttributes
 * @return
 */
@RequestMapping(value="/view04")
public String view04(RedirectAttributes redirectAttributes){
    redirectAttributes.addAttribute("uname","张三");
    redirectAttributes.addAttribute("upwd","123456");
    return "redirect:view.jsp";
}
/**
 * 重定向到JSP⻚⾯
 * 返回 ModelAndView 对象
 * @param modelAndView
 * @return
 */
@RequestMapping(value="/view06")
public ModelAndView view06(ModelAndView modelAndView){
    modelAndView.addObject("uname","李四");
    modelAndView.addObject("upwd","123321");
    modelAndView.setViewName("redirect:view.jsp");
    return modelAndView;
}
/**
 * 重定向到Controller
 * 返回 ModelAndView 对象
 * @param modelAndView
 * @return
 */
@RequestMapping(value="/view07")
public ModelAndView view07(ModelAndView modelAndView){
    modelAndView.addObject("uname","admin");
    modelAndView.setViewName("redirect:test01");
    return modelAndView;
}

⻚⾯中获取参数值

${param.参数名}

5.2 请求转发

请求转发,直接调⽤跳转的⻚⾯,让它返回。对于浏览器来说,它⽆法感觉服务器有没有forward。地址栏不发⽣改变。可以获取请求域中的数据。

请求转发以 forward: 开头

/**
 * 请求转发到JSP⻚⾯
 */
@RequestMapping("/view08")
public String view08(){
    return "forward:view.jsp";
}
/**
 * 请求转发到JSP⻚⾯
 * 设置参数
 */
@RequestMapping("/view09")
public String view09(){
    return "forward:view.jsp?uname=张三&upwd=123456";
}
​
/**
 * 请求转发到JSP⻚⾯
 * 设置请求域
 */
@RequestMapping("/view10")
public String view10(Model model){
    model.addAttribute("uname","张三");
    return "forward:view.jsp";
}
/**
 * 请求转发到JSP⻚⾯ (默认)
 * 默认会去指定⽬录下找JSP⻚⾯ (配置⽂件中设置的)
 */
@RequestMapping("/view11")
public String view11(){
    return "/../../view";
}
/**
 * 请求转发到 Controller
 * @return
 */
@RequestMapping("/view12")
public ModelAndView view12(ModelAndView modelAndView){
    modelAndView.setViewName("forward:test01");
    return modelAndView;
}
/**
 * 请求转发到 Controller
 * 传递参数
 * @return
 */
@RequestMapping("/view13")
public ModelAndView view13(ModelAndView modelAndView){
    modelAndView.setViewName("forward:test01?uname=admin");
    return modelAndView;
}

⻚⾯中获取数据

获取传递的参数:${param.参数名}
获取请求域的数据:${请求域中设置的名称}

6.JSON数据开发

6.1 基本概念

Json 在企业开发中已经作为通⽤的接⼝参数类型,在⻚⾯(客户端)解析很⽅便。SpringMVC 对于json 提供了良好的⽀持,这⾥需要修改相关配置,添加 json 数据⽀持功能。

6.1.1 @ResponseBody

该注解⽤于将 Controller 的⽅法返回的对象,通过适当的 HttpMessageConverter 转换为指定格式后,写⼊到 Response 对象的 body 数据区。

返回的数据不是 html 标签的⻚⾯,⽽是其他某种格式的数据时(如 json、xml 等)使⽤(通常⽤于ajax请求)。

6.1.2 @RequestBody

该注解⽤于读取 Request 请求的 body 部分数据,使⽤系统默认配置的 HttpMessageConverter 进⾏解析,然后把相应的数据绑定到要返回的对象上 ,再把 HttpMessageConverter 返回的对象数据绑定到controller 中⽅法的参数上。

6.2 使用配置

6.2.1 添加json相关坐标

pom.xml

<!-- 添加json 依赖jar包 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.10.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.0</version>
</dependency> 
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.10.0</version>
</dependency>
6.2.2 修改配置⽂件

servlet-context.xml

<!-- mvc 请求映射 处理器与适配器配置 -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
        <bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>
6.2.3 注解使用
6.2.3.1 @ResponseBody
@Controller
@RequestMapping("/user")
public class UserController {
    /**
     * @ResponseBody 返回的是JOSN格式的数据,返回JavaBean对象
     * 注解设置在⽅法体上
     * @return
     */
    @RequestMapping("queryUser01")
    @ResponseBody
    public User queryUser01(){
        User user = new User();
        user.setId(1);
        user.setUserName("zhangsan");
        user.setUserPwd("123456");
        // 返回的是user对象
        return user;
    }
    /**
     * @ResponseBody 返回的是JOSN格式的数据,返回JavaBean对象
     * 注解设置在⽅法返回对象前,修饰符之后
     * @return
     */
    @RequestMapping("queryUser02")
    public @ResponseBody User queryUser02(){
        User user = new User();
        user.setId(2);
        user.setUserName("lisi");
        user.setUserPwd("123321");
        // 返回的是user对象
        return user;
    }
​
    /**
    * @ResponseBody 返回的是JOSN格式的数据,返回集合
    * @return
    */
    @RequestMapping("queryUser02")
    public @ResponseBody User queryUser02(){
        User user = new User();
        user.setId(2);
        user.setUserName("lisi");
        user.setUserPwd("123321");
        // 返回的是user对象
        return user;
    }
​
    /**
     * @ResponseBody 返回的是JOSN格式的数据,返回集合
     * @return
     */
    @RequestMapping("/queryUser03")
    @ResponseBody
    public List<User> queryUser03(){
        List<User> list = new ArrayList<>();
        User user01 = new User();
        user01.setId(1);
        user01.setUserName("zhangsan");
        user01.setUserPwd("123456");
        User user02 = new User();
        user02.setId(2);
        user02.setUserName("lisi");
        user02.setUserPwd("123321");
        list.add(user01);
        list.add(user02);
        // 返回的是user集合
        return list;
    }
}
6.2.3.2 @RequestBody

@RequestBody 注解常⽤来处理 content-type 不是默认的 application/x-www-form-urlcoded 类型的内容,⽐如说:application/json 或者是application/xml 等。⼀般情况下来说常⽤其来处理 application/json类型。@RequestBody接受的是⼀个 json 格式的字符串,⼀定是⼀个字符串。

通过 @RequestBody 可以将请求体中的 JSON 字符串绑定到相应的 bean 上,当然,也可以将其分别绑定到对应的字符串上。

/**
 * @RequestBody 规定请求的参数是JOSN格式的字符串
 * 注解设置在形参前⾯
 * @param user
 * @return
 */
@RequestMapping("/getUser")
@ResponseBody
public User getUser(@RequestBody User user){
    System.out.println(user);
    return user;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kube-Prometheus-Stack安装时初始化导入自定义Grafana dashboards

获取Grafana dashboards的JSON文件 这里是获取已经编辑好的Grafana dashboards的JSON文件&#xff1b;以便内置到Kube-Prometheus-Stack的helm charts的安装zip文件中。 编辑自定义dashboards JSON文件 获取dashboards JSON文件模板 其实Kube-Prometheus-Stack内部本身已经内…

手机租赁系统开发全攻略 创新服务助力企业智能转型

内容概要 在当今数字化飞速发展的时代&#xff0c;“手机租赁系统开发”正逐渐成为企业智能转型的必然选择。这一过程并不简单&#xff0c;但关键流程的解析将帮助企业理清思路。首先&#xff0c;了解需求和目标是基础&#xff0c;之后制定详细计划和流程图&#xff0c;让整件…

中安证件OCR识别技术助力鸿蒙生态:智能化证件识别新体验

在数字化和智能化的浪潮中&#xff0c;伴随国产化战略的深入推进&#xff0c;国产操作系统和软件生态的建设逐渐走向成熟。鸿蒙操作系统&#xff08;HarmonyOS Next&#xff09;作为华为推出的重要操作系统&#xff0c;凭借其开放、灵活和高效的特点&#xff0c;正在加速在多个…

Python_Flask03

这篇文章主要介绍的是数据库的增删改查操作&#xff0c;无多余好说的。 from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy import text from flask_migrate import Migrateapp Flask(__name__)# 本地基础信息的主机名 HOSTNAME "127.0…

Flink问题总结

目录 1、Flink 的四大特征(基石) 2、Flink 中都有哪些 Source,哪些 Sink,哪些算子(方法) 3、什么是侧道输出流,有什么用途 4、Flink 中两个流如何合并为一个流 5、Flink 中两个流如何 join 6、Flink 中都有哪些 window,什么是滑动,滚动窗口 7、flink 中都有哪些…

Q、K、V怎样学习到不同的特性;注意力机制和自注意力区别

目录 Q、K、V怎样学习到不同的特性 注意力机制和自注意力区别 Q、K、V怎样学习到不同的特性 Q = XW_Q:Query向量表示“我想要找什么”,通过输入向量X与权重矩阵W_Q的乘积得到。K = XW_K:Key向量表示“我有什么”,通过输入向量X与权重矩阵W_K的乘积得到。V = XW_V:Value向…

MySQL 入门大全:常用函数

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

Python酷库之旅-第三方库Pandas(259)

目录 一、用法精讲 1226、pandas.tseries.offsets.Week.name属性 1226-1、语法 1226-2、参数 1226-3、功能 1226-4、返回值 1226-5、说明 1226-6、用法 1226-6-1、数据准备 1226-6-2、代码示例 1226-6-3、结果输出 1227、pandas.tseries.offsets.Week.rule_code属性…

《操作系统 - 清华大学》6 -5:局部页面置换算法:改进的时钟页面置换算法

文章目录 1. 改进的时钟置换算法的工作原理2. 改进的时钟置换算法示例 1. 改进的时钟置换算法的工作原理 Clock 算法使用页表项中很重要的 access bit 来表明这个页的访问信息&#xff0c;但需要注意&#xff0c;读和写都是访问&#xff0c;并没有区分到底是读还是写&#xff0…

【六足机器人】03步态算法

温馨提示&#xff1a;此部分内容需要较强的数学能力&#xff0c;包括但不限于矩阵运算、坐标变换、数学几何。 一、数学知识 1.1 正逆运动学&#xff08;几何法&#xff09; 逆运动学解算函数 // 逆运动学-->计算出三个角度 void inverse_caculate(double x, double y, …

【WRF后处理】WRF时区(UTC)需转化为北京时间(CST)!!!

目录 WRF运行时间标准注意事项-本地时区问题 输入数据&#xff1a;ERA5时间标准ERA5数据和WRF模型需要转换为北京时间&#xff01;&#xff01;&#xff01;北京时间&#xff08;CST&#xff09;与协调世界时&#xff08;UTC&#xff09;的关系转换方法 参考 WRF运行时间标准 …

如何撰写标准操作流程(SOP):9个快速步骤

要了解一个公司日常的实际运营情况&#xff0c;只需查看他们的标准操作流程&#xff08;SOP&#xff09;即可。 尽管SOP在任何成功组织中都扮演着至关重要的角色&#xff0c;但它们往往声名不佳。 人们通常认为&#xff0c;这些针对日常任务的详细指令只是为了限制员工的灵活性…

InfluxDB 集成 Grafana

将InfluxDB集成到Grafana进行详细配置通常包括以下几个步骤&#xff1a;安装与配置InfluxDB、安装与配置Grafana、在Grafana中添加InfluxDB数据源以及创建和配置仪表板。以下是一个详细的配置指南&#xff1a; 一、安装与配置InfluxDB 下载与安装&#xff1a; 从InfluxDB的官…

SpringBoot项目启动报错-Slf4j日志相关类找不到

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

AI新动向:豆包文生图升级,文心一言领先市场

在今日的AI资讯中&#xff0c;我们关注到了几个重要的行业动态&#xff0c;其中包括字节跳动AI助手豆包的功能升级&#xff0c;以及百度文心一言在生成式AI市场的领先地位。 字节跳动旗下的智能AI助手豆包近期对其文生图能力进行了显著提升&#xff0c;用户现在可以通过一键操…

企业网双核心交换机实现冗余和负载均衡(MSTP+VRRP)

MSTP&#xff08;多生成树协议&#xff09; 通过创建多个VLAN实例&#xff0c;将原有的STP、RSTP升级&#xff0c;避免单一VLAN阻塞后导致带宽的浪费&#xff0c;通过将VLAN数据与实例绑定&#xff0c;有效提升网络速率。 VRRP&#xff08;虚拟路由冗余协议&#xff09; 用…

使用Edu教育邮箱免费使用JetBrains专业版

需要准备的原料&#xff1a; 1个Edu邮箱&#xff08;最好是公立大学&#xff09; / JetBrains账户 Edu邮箱是什么&#xff1f; Edu邮箱是由美国高校和教育机构发放的邮箱&#xff0c;通常以“edu”结尾。拥有这个邮箱&#xff0c;你不仅能享受校园内的各种福利&#xff0c;还能…

️️耗时一周,肝了一个超丝滑的卡盒小程序

前言 先看看成品效果&#xff1a; 在上个月&#xff0c;我出于提升自己的英语造句能力的目的&#xff0c;想要找一个阅读或者练习造句类的英语学习 APP&#xff0c;但是最终找了几个 APP 不是不太好用就是要付费。于是我转换思路&#xff0c;找到了一本书&#xff0c;叫《36…

初学者微服务Nocos快速了解使用

Windows安装部署nacos 1.Windows启动nacos服务 下载nacos安装包&#xff1a;下载地址&#xff08;需要梯子访问&#xff09;&#xff1a;https://github.com/alibaba/nacos/releases 2.解压安装包&#xff0c;不要将nacos放置在中文路径下 3.在bin目录下双击startup.cmd文件 4.…

Qt Quick 开发基础 + 实战(持续更新中…)

最近更新日期&#xff1a;2024/12/5 目录 一、Qt Quick简介 1.3 新建Qt Quick Application工程 1.3.1 导入Qt资源文件 1.3.2 设置应用图标&#xff08;Windows系统&#xff09; 二、QML 2.2 import 2.2.1 import模块 2.2.2 import代码文件 2.3 属性&#xff1a;proper…