关于spring:SpringMVC请求与响应的处理实战一

48次阅读

共计 11582 个字符,预计需要花费 29 分钟才能阅读完成。

后期筹备

应用环境

  • JDK:1.8
  • Tomcat:9.0.3
  • Spring:5.2.8
  • Maven:3.6.3
  • 编译器:IntelliJ IDEA 2019

web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
 version="4.0">
     
     <servlet> 
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param> 
            <param-name>contextConfigLocation</param-name>
        <param-value>classpath:ApplicationContext.xml</param-value>
        </init-param> 
    </servlet>
    <servlet-mapping> 
        <servlet-name>mvc</servlet-name>
        <url-pattern>*.do</url-pattern>
     </servlet-mapping>
</web-app>

ApplicationContext.xml 配置(Spring 外围配置文件)

<?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:aop="http://www.springframework.org/schema/aop"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 https://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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 开启 spring 注解驱动 -->
     <context:component-scan base-package="com.cjh"/>
    <!-- 开启 mvc 注解驱动 -->
     <mvc:annotation-driven></mvc:annotation-driven>
</beans>

申请

1. 申请的发送与接管

以下写的浏览器和服务器的形式是绝对应的,比方第一种申请就对应着第一种接管

  • 1)浏览器发送申请的形式:

    • 第一种:申请资源名(找的是具体的解决类),申请的办法上写上 @RequestMapping 注解

      • 这种模式要求申请的解决类下只有一个办法
    • 第二种:申请资源名?method= 具体执行办法(找的是具体的解决类中的办法)
    • 第三种:申请资源名(找的是具体的执行办法)—– 罕用
  • 2)服务器接管申请的形式:

    • 不论是对应浏览器的哪种发送形式,都须要应用 @RequestMapping 注解
    • 第一种:在类上写上 @RequestMapping(申请资源名) 注解
    • 第二种:在类上写上 @RequestMapping(申请资源名) 注解,在办法上也要写上 @RequestMapping(params = {method= 办法名}) 注解(method 也能够换成其余名字)
    • 第三种:间接在办法上写上 @RequestMapping(申请资源名)
  • 3)@RequestMapping 注解中的其余办法

    • path/value:用来存储申请资源名
    • params:要求浏览器必须发送的参数,参数的模式是 {“key=value”,””},
    • method:要求浏览器申请的办法(GET/POST)
    • headers:要求浏览器必须携带的申请头({“Accept-Language”,””})
    • 留神:前面三个一旦写明,就是要求浏览器必须携带的货色,如果没有携带,那么服务器是不解决的
  • 4)具体示例代码:

    • 第一种形式:

      • JSP
      <%@ page contentType="text/html; charset=UTF-8" language="java" %>
      <html>
      <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>cai jin hong</title>
       <style>
       </style>
      </head>
      <body>
       <a href="userController.do"> 测试第一种申请形式 </a>
      </html>
      • java
      @Controller
      @RequestMapping("userController.do")
      public class UserController {
      
          @RequestMapping
          public void testOne(){System.out.println("test 办法执行了");
          }
      }
      • 测试后果:浏览器显示 404,服务器控制台打印出 test 办法执行了
    • 第二种形式:

      • JSP
      <%@ page contentType="text/html; charset=UTF-8" language="java" %>
      <html>
      <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>cai jin hong</title>
       <style>
       </style></head>
      <body>
       <a href="userController.do?method=testOne"> 测试 userController 下的 testOne 办法 </a><br>
       <a href="userController.do?method=testTwo"> 测试 userController 下的 testTwo 办法 </a>
      </body>
      </html>
      • java
      @Controller
      @RequestMapping("userController.do")
      public class UserController {@RequestMapping(params = {"method=testOne"})
          public void testOne(){System.out.println("testOne 办法执行了");
          }
          @RequestMapping(params = {"method=testTwo"})
          public void testTwo(){System.out.println("testTwo 办法执行了");
          }
      }
      • 测试后果:浏览器显示 404,服务器控制台打印出输入的语句
    • 第三种形式:

      • JSP:
      <%@ page contentType="text/html; charset=UTF-8" language="java" %>
      <html>
      <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>cai jin hong</title>
       <style>
       </style></head>
      <body>
       <a href="testOne.do">testOne 办法 </a><br>
       <a href="testTwo.do">testTwo 办法 </a>
      </body>
      </html>
      • Java:
      @Controller
      public class UserController {@RequestMapping("testOne.do")
          public void testOne(){System.out.println("testOne 办法执行了");
          }
          @RequestMapping("testTwo.do")
          public void testTwo(){System.out.println("testTwo 办法执行了");
          }
      }
      • 测试后果:浏览器显示 404,服务器端控制台失常打印
    • @RequestMapping 的其余用法

      • JSP:
      <%@ page contentType="text/html; charset=UTF-8" language="java" %>
      <html>
      <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>cai jin hong</title>
       <style>
       </style></head>
      <body>
       <a href="testOne.do?user=123&password=123"> 测试参数携带的申请 </a><br>
       <a href="testOne.do"> 测试不携带参数的申请 </a>
      <%--    a 标签的申请形式是 GET 申请 --%>
       <a href="testGetMethod.do"> 测试服务器要求的申请形式 </a>
       <a href="testPostMethod.do"> 测试服务器要求的申请形式 </a>
       <a href="testHeader.do"> 测试服务器要求的携带的申请头 </a>
      </body>
      </html>
      • Java:
      @Controller
      public class UserController {
          // 申请必须携带 user 和 password 这两个参数 key,而且必须有 value 值
          @RequestMapping(value = "testOne.do", params = {"user=123", "password=123"})
          public void testOne(){System.out.println("这是测试是否携带参数的申请办法");
           }
          @RequestMapping(value = "testGetMethod.do", method = {RequestMethod.GET})
          public void testGetMethod(){System.out.println("这是测试 Get 的申请办法");
          }
          @RequestMapping(value = "testPostMethod.do", method = {RequestMethod.POST})
          public void testPostMethod(){System.out.println("这是测试 Post 的申请办法");
          }
          @RequestMapping(value = "testHeader.do", headers = {"Accept-Language"})
          public void testHeader(){System.out.println("这是测试是否携带申请头");
          }
      }
      • 测试后果:
      • 测试参数携带的申请

        • 浏览器显示 404,客户端失常打印
      • 测试不携带参数的申请

        • 浏览器显示 400 报错,不满足客户端要求的格局
      • 测试服务器要求的 GET 申请形式

        • 浏览器显示 404,客户端失常打印
      • 测试服务器要求的 POST 申请形式

        • 浏览器显示 405,申请的资源要求用 Post 形式,不反对 GET 申请
      • 测试服务器要求携带的申请头

        • 浏览器显示 404,客户端失常打印

2. 申请参数的解决

  • 1)办法中传入变量

    • 要求传入的变量与浏览器发送申请传递的参数 key 统一,即使 key 只有一个
    • 利用 @RequestParam(“key”),那么只需注解外面的 key 和浏览器传递的参数 key 统一即可
    • 代码如下:

      • JSP:
      <%@ page contentType="text/html; charset=UTF-8" language="java" %>
      <html>
      <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>cai jin hong</title>
       <style>
       </style></head>
      <body>
       <form action="testOne.do" method="post">
       <input type="text" name="account" value=""><br>
       <input type="text" name="password" value=""><br>
       <input type="text" name="balance" value=""><br>
       <input type="submit" value="submit">
       </form>
       <form action="testTwo.do" method="post">
       <input type="text" name="account" value=""><br>
       <input type="text" name="password" value=""><br>
       <input type="text" name="balance" value=""><br>
       <input type="submit" value="submit">
       </form>
        </body>
      </html>
      • Java:
      @Controller
      public class UserController {
          // 办法中传入变量:参数名与申请传递参数的名字统一
          @RequestMapping("testOne.do")
          public void testOne(String account, String password, float balance){System.out.println("testOne:"+ "account =" + account + "password =" + password + "balance" + balance);
       }
          // 办法中传入变量:参数名与申请传递参数的名字不统一
          @RequestMapping("testTwo.do")
          public void testTwo(@RequestParam("account") String xxx,    @RequestParam("password") String yyy, @RequestParam("balance") float zzz){System.out.println("testTwo:" + "account =" + xxx + "password =" + yyy + "balance" + zzz);
          }
      
      }
      • input 标签里的内如本人输出,点击 submit,在后端的管制台上就能看到打印进去的后果
  • 2)办法中传入实体对象

    • 间接用对象接管,要求对象中的属性名与浏览器传递过去的参数 key 统一

      • 代码如下:
      • JSP:(代码太多了,这里只给出 form 表单)
      <form action="testThree.do" method="post">
       <input type="text" name="account" value=""><br>
       <input type="text" name="password" value=""><br>
       <input type="text" name="balance" value=""><br>
       <input type="submit" value="submit">
      </form>
      • Java:
      public class User {
          private String account;
       private String password;
       private Float balance;
       public User(String account, String password, Float balance) {System.out.println("User:带参的构造方法");
       this.account = account;
       this.password = password;
       this.balance = balance;
       }
          public User(){System.out.println("User:无参的构造方法");
       }
          public void init(){System.out.println("初始化了");
       }
          public void destroy(){System.out.println("被销毁了");
       }
          @Override
       public String toString() {
              return "User{" +
                      "account='" + account + '''+", password='"+ password +''' +
                      ", balance=" + balance +
                      '}';
       }
          public String getAccount() {return account;}
          public void setAccount(String account) {System.out.println("set 办法调用了");
       this.account = account;
       }
          public String getPassword() {return password;}
          public void setPassword(String password) {this.password = password;}
          public Float getBalance() {return balance;}
          public void setBalance(Float balance) {this.balance = balance;}
      }
      @Controller
      public class UserController {@RequestMapping("testThree.do")
          // 办法中传入实体对象:要求对象中的属性名与浏览器传递过去的参数 key 统一
           public void testThree(User user){System.out.println("testThree:"+ user);
           }
      }
    • 对象套对象的状况:Spring 会依据传递过去的参数,将对象里对象属性主动包装(如果参数名和属性名都对应的话)

      • 代码如下:
      • JSP:
      <form action="testThree.do" method="post">
       account:<input type="text" name="account" value=""><br>
       password:<input type="text" name="password" value=""><br>
       balance:<input type="text" name="balance" value=""><br>
       address:<input type="text" name="address" value=""><br>
       <input type="submit" value="submit">
      </form>
      • Java:(User 外面套着 Address)
      public class Address {
          private String address;
           public Address(){}
              public Address(String address){this.address = address;}
              @Override
           public String toString() {
                  return "Address{" +
                          "address='" + address + '''+'}';
           }
              public void setAddress(String address) {this.address = address;}
              public String getAddress() {return address;}
      }
      public class User {
          private String account;
           private String password;
           private Float balance;
           private Address address;
           public User(String account, String password, Float balance) {System.out.println("User:带参的构造方法");
           this.account = account;
           this.password = password;
           this.balance = balance;
           }
              public User(){System.out.println("User:无参的构造方法");
           }
              public void init(){System.out.println("初始化了");
           }
              public void destroy(){System.out.println("被销毁了");
           }
              @Override
           public String toString() {
                  return "User{" +
                          "account='" + account + '''+", password='"+ password +''' +
                          ", balance=" + balance +
                          ", address=" + address +
                          '}';
           }
              public String getAccount() {return account;}
              public void setAccount(String account) {System.out.println("set 办法调用了");
           this.account = account;
           }
              public String getPassword() {return password;}
              public void setPassword(String password) {this.password = password;}
              public Float getBalance() {return balance;}
              public void setBalance(Float balance) {this.balance = balance;}
              public void setAddress(Address address) {this.address = address;}
              public Address getAddress() {return address;}
          }
          @Controller
          public class UserController {
              // 办法中传入实体对象:对象外面依赖了其余对象
           @RequestMapping("testFour.do")
              public void testFour(User user){System.out.println("testFour:" + user);
           }
      }
      • 留神:输出中文会呈现乱码的问题,因为这里没有解决中文字符集
    • 对象套 list 汇合 < 对象 >:

      • 代码如下:
      • JSP:(addressList[i] 代表 addressList 汇合中的一个对象,通过. 获取对象的属性,addressList 是 user 对象中的属性名)
      <form action="testFive.do" method="post">
       account:<input type="text" name="account" value=""><br>
       password:<input type="text" name="password" value=""><br>
       balance:<input type="text" name="balance" value=""><br>
       address1:<input type="text" name="addressList[0].address" value=""><br>
       address2:<input type="text" name="addressList[1].address" value=""><br>
       <input type="submit" value="submit">
      </form>
      • Java:(Address 类代码不变)
      public class User {
          private String account;
           private String password;
           private Float balance;
           private List<Address> addressList;
           public User(String account, String password, Float balance) {System.out.println("User:带参的构造方法");
           this.account = account;
           this.password = password;
           this.balance = balance;
           }
              public User(){System.out.println("User:无参的构造方法");
           }
              public void init(){System.out.println("初始化了");
           }
              public void destroy(){System.out.println("被销毁了");
           }
              @Override
           public String toString() {
                  return "User{" +
                          "account='" + account + '''+", password='"+ password +''' +
                          ", balance=" + balance +
                          ", addressList=" + addressList +
                          '}';
           }
              public String getAccount() {return account;}
              public void setAccount(String account) {System.out.println("set 办法调用了");
           this.account = account;
           }
              public String getPassword() {return password;}
              public void setPassword(String password) {this.password = password;}
              public Float getBalance() {return balance;}
              public void setBalance(Float balance) {this.balance = balance;}
              public void setAddressList(List<Address> addressList) {this.addressList = addressList;}
              public List<Address> getAddressList() {return addressList;}
      }
      
      @Controller
      public class UserController {
      
          // 办法中传入实体对象:对象外面有 list 汇合
       @RequestMapping("testFive.do")
          public void testFive(User user){System.out.println("testFive:" + user);
       }
      
      }
  • 3)办法中传入 Map 汇合

    • 间接在办法参数前加上 @RequestParam 注解(这里就不写了)
  • 4)办法中传入 Request、Response 对象

    • 代码如下:
    @RequestMapping("testFive.do")
    public void testFive(HttpServletRequest request, HttpServletResponse response){System.out.println(request.getParameter("account"));
     System.out.println(response);
    }

本篇文章到这就完结了,因为篇幅比拟长,把响应的解决放在下一篇文章中!!!

正文完
 0