SpringMVC简介

  • SpringMVC,控制! Control
  • SpringMVc是控制层的框架(Model,View,Control),主要是一种思想
    • 前台请求发过来,控制层Control调用Model去处理
    • 处理的结果以json字符串的形式返回,也有在浏览器处理后返回页面的,不多

get请求

get请求

  • get请求,GetMapping接收,用PostMapping接收报错
  • get请求的信息显示在浏览器的地址栏中,不安全

post请求

  • post请求,PostMapping接收,用PostMapping接收报错
  • post请求的信息不会显示在浏览器的地址栏中

get请求和post请求都可以用RequestMapping接收

static目录下index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Insert title here</title>
  6. </head>
  7. <body>
  8. <h1>Get</h1>
  9. <form action="/reg1" method="get">
  10. <input type="text" name="username">
  11. <input type="text" name="pwd">
  12. <input type="submit" value="put">
  13. </form>
  14. <h1>Post</h1>
  15. <form action="/reg2" method="post">
  16. <input type="text" name="username">
  17. <input type="text" name="pwd">
  18. <input type="submit" value="put">
  19. </form>
  20. <h1>Get|Post</h1>
  21. <form action="/reg3" method="Get">
  22. <input type="text" name="username">
  23. <input type="text" name="pwd">
  24. <input type="submit" value="put">
  25. </form>
  26. <h1>Get|Post</h1>
  27. <form action="/reg3" method="post">
  28. <input type="text" name="username">
  29. <input type="text" name="pwd">
  30. <input type="submit" value="put">
  31. </form>
  32. </body>
  33. </html>

必须是在controller包下才能通过注解RestController访问里面的方法

package com.tedu.springb.controller;

@RestController
public class UseController {
    //被@RestController注解的类必须在    包路径.control 下才能起作用
    //每个@RestController注解的类都是单例,项目运行时自动执行方法创建唯一对象
    public UseController() {
        System.out.println("无参构造方法");
    }

    //get请求,GetMapping接收,用PostMapping接收报错,多个人访问对象地址值不变,单例
    @GetMapping("/reg1")
    public String register1(String username,String pwd) {
        return username+","+pwd+"注册成功"+"|"+this.toString();
    }

    //post请求,PostMapping接收,用GetMapping接收报错
    @PostMapping("reg2")
    public String register2(String username,String pwd) {
        return username+","+pwd+"注册成功";
    }

    //RequestMapping可以接收get和post两种请求
    @RequestMapping("reg3")
    public String register3(String username,String pwd) {
        return username+","+pwd+"注册成功";
    }

    //新建对象User,添加get、set方法,传入对象参数
    //http://localhost:8088/reg5?username=iu&pwd=18
    @RequestMapping("reg4")
    public String register4(User user){
        return user.getUsername()+","+user.getPwd();
    }
}

Request,response对象

  • 请求与响应

image.png

package com.tedu.springb.controller;

@RestController
public class UseController {
    //模拟网页版请求
    @RequestMapping("/reg5") //http://localhost:8088/reg5?username=iu&pwd=18
    public String register5(HttpServletRequest request) {
        String name = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        //获得请求主机地址
        String id = request.getRemoteAddr();
        return name+","+pwd+","+id ;
    }

    //模拟响应
    @RequestMapping("/reg6")
    public void register6(HttpServletRequest request,HttpServletResponse response)throws Throwable {
        String name = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        String id = request.getRemoteAddr();
        String string =  name+","+pwd+","+id ;

        //告诉浏览器返回数据类型
        response.setContentType("text/html");
        //告诉浏览器返回数据的字符集是utf-8
        response.setCharacterEncoding("UTF-8");
        PrintWriter printWriter = response.getWriter();
        printWriter.println(string);
    }
}

Cookie

  • cookie是你访问某个网站的身份证,每次你访问网站都会把你本地的所有cookie传给网站,当你是第一次访问网站时,网站给你写入cookie

    添加cookie

  • 服务器往浏览器写入cookie,response

    @RestController
    public class UseController {
      @RequestMapping("/login")
      public String login(String name,HttpServletResponse response) {
          Cookie cookie = new Cookie("baidu_id", "429004**");
          response.addCookie(cookie);
          return "设置了cookie";
      }
    }
    

    展示cookie信息

  • 浏览器请求,cookie传到服务器,request

    @RestController
    public class UseController {
      @RequestMapping("/list")
      public String list(String name,HttpServletRequest request) {
          //获得全部cookie,是个数组
          Cookie cookies[] = request.getCookies();
          String string = "";
          if(cookies != null) {
              //遍历cookie数组
              for (Cookie cookie : cookies) {
                  string = cookie.getName()+":"+cookie.getValue();
              }
          }
          return string;
      }
    }
    

    Cookie生存周期

    @RestController
    public class UseController {
      @RequestMapping("/setLive")
      public String setCookielive(HttpServletResponse response) {
          //不设置浏览器关闭就消失
          Cookie cookie1 = new Cookie("bai_du", "429004***");
          response.addCookie(cookie1);
    
          Cookie cookie2 = new Cookie("tao_bao", "888888***");
          cookie2.setMaxAge(60*2);
          response.addCookie(cookie2);
    
          return "设置cookie存活时间";        
      }
    }
    

    Session

    session使用

  • session是存在于服务器端的信息,相当于小型数据库

  • 需求:商城购物车
  • 业务逻辑
    • 当添加商品时,用户的请求首先到session中查找,首先在session第一层hashmap结构中(cookie值,hashmap)比较,比较cookie,找不到,就给浏览器设置cookie在进行添加,找到了就就进入第二层hashmap(购物车标识,购物车商品集合),添加进入购物车集合
    • 展示商品时,浏览器的cookie会跟着用户的请求传给服务器,让服务器知道这是哪个人,
  • 添加到购物车,服务器先分cookie过来,是response
  • 请求显示商品,浏览器cookie全部跟着请求传到了服务器,是request

SpringMVC - 图2

  • 111 和 222是cookie值 ```java package com.tedu.mvcDemo.controller;

import java.util.ArrayList; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

@RestController public class CartController { @RequestMapping(“/add”) //添加商品到购物车,因此添加时会服务器会设置cookie到浏览器,response public String addCart(String itemName,HttpSession session) { //session内部是有hashmap,用来存放数据 //查看session内部有没有键cartList对应的集合,没有就建立这个集合cartLists ////这个集合就是购物车 ArrayList cartLists = (ArrayList) session.getAttribute(“cartList”); if(cartLists == null) { cartLists = new ArrayList(); //session中保存购物车键值对,键是cartList,值是全部商品的集合 session.setAttribute(“cartList”, cartLists); } //商品添加到购物车集合 cartLists.add(itemName); return “添加商品”+itemName+”到购物车”; } //向服务器请求,发送全部cookie过去,request @RequestMapping(“list”) public String list(HttpServletRequest request,HttpSession session) { //显示全部cookie Cookie cookies[] = request.getCookies(); String string = “”; if(cookies != null) { for (Cookie cookie : cookies) { string = string + cookie.getName()+”:”+cookie.getValue(); } } // 找到购物车集合 ArrayList cartLists = (ArrayList) session.getAttribute(“cartList”); // 判断购物车是否为空 if(cartLists != null) { // 遍历商品 for (String item : cartLists) { string = string +”
“+item; } } return string; } }


- 不同的浏览器就像不同的用户一样,访问时服务器会重新分配身份证--cookie
<a name="YwRd7"></a>
### Cookie与sessoin的关系

- Session的数据是存在服务器内存中,服务器重启数据就没了。
- Session是用临时cookie实现的,浏览器一关数据就没有了。如何实现在浏览器中添加购物车,在手机端查看呢?解决思路把购物商品放到数据库中,通过用户名从数据库查找购物商品。
- Cookie的数据是存在浏览器中的
<a name="s1CMe"></a>
## Controller
<a name="Lk16v"></a>
### @RestController返回json字符串

- 业务逻辑
   - 发过来的请求被后台处理后变成对象返回给springmvc,在返回前台之前,SpringMVC框架将调用它里面的jackson框架处理对象为json字符串返回前台

![image.png](https://cdn.nlark.com/yuque/0/2021/png/358364/1610804808027-0a2bbb0d-ddfc-49f4-bb43-e6d6d4cd5fc7.png#align=left&display=inline&height=344&margin=%5Bobject%20Object%5D&name=image.png&originHeight=688&originWidth=979&size=57013&status=done&style=none&width=489.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/358364/1610804828967-c7741875-4647-4257-ac79-e8c6fdac6222.png#align=left&display=inline&height=308&margin=%5Bobject%20Object%5D&name=image.png&originHeight=616&originWidth=1072&size=88702&status=done&style=none&width=536)
```java
package com.tedu.mvcDemo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UseController {
    //加了@RestController后,框架会自动创建对象
    @RequestMapping("find")
    public Item find() {
        //模拟返回数据库中的数据
        Item item = new Item();
        item.setName("oppo Ace");
        item.setPrice(66);
        //返回的是对象,框架会自动调用 jackson把对象转成json
        return item;
    }
}

Jsp显示商品信息

返回页面JSP(html页面) (@Controller)

1、添加依赖

<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
</dependency>

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>

2、创建Item类,商品名称、商品价格添加get、set方法,构造方法
3、创建Jsp页面

  • 在src\main下创建文件夹webapp\WEB-INF\jsp
  • image.png
  • 右键创建list.jsp,修改字符集为UTF-8

    <%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    jsp
    </body>
    </html>
    

    4、修改application.properties

  • 设置jsp的前缀和后缀。强制把jsp放在/WEB-INF/jsp文件夹中。设置后在controller通过文件名list就可以访问/WEB-INF/jsp/list.jsp

    spring.mvc.view.prefix=/WEB-INF/jsp/
    spring.mvc.view.suffix=.jsp
    

    5、创建controller

    //@restController返回json
    @Controller//返回jsp
    public class ItemJspController {
      @RequestMapping("/listItem")
      public ModelAndView listItem() {
          //返回web-inf/jsp/list.jsp,View指的是界面,就是jsp
          ModelAndView modelAndView=new ModelAndView("list");
          return modelAndView;
      }    
    }
    
  • @Controller配合ModelAndView返回Jsp

Jstl展现商品信息的jsp页面(@Controller)

  • JSTL(Java server pages standarded tag library,即JSP标准标签库),使用jstl可以很方便的在jsp中显示java数据,拷贝taglib标签。
  • JSTL使用
    • 在list.jsp中加入就可以使用JSTL了
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
      
      <%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8"%>
      <!--导入即可使用jstl语法  -->
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="UTF-8">
      <title>Insert title here</title>
      </head>
      <body>
      <table border="2">
         <tr>
             <td>商品名称</td><td>商品价格</td>
         </tr>
         <!--jstl语法,获得商品列表集合itemList,给每个商品一个变量指代item ,遍历 -->
         <c:forEach items="${itemList }" var="item">
         <tr>
             <td>${item.name }</td><td>${item.price }</td>
         </tr>
         </c:forEach>
      </table>
      </body>
      </html>
      
      ```java package com.tedu.springb.controller;

import java.util.ArrayList; import java.util.List;

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

//返回json字符串用@RestController //返回jsp用@Controller @Controller public class UseController { @RequestMapping(“/listItem”) public ModelAndView backJsp() { //创建商品列表集合 List itemList = new ArrayList(); Item item1 = new Item(“oppo”, 66); Item item2 = new Item(“mate10”, 77); itemList.add(item1); itemList.add(item2); //返回web-inf/jsp/list.jsp,View指的是界面,就是jsp ModelAndView modelAndView = new ModelAndView(“list”); //将页面信息通过itemList键传给Jsp页面渲染 modelAndView.addObject(“itemList”, itemList); return modelAndView; } }


- 将控制层的商品信息集合信息通过键itemList传给JSP页面渲染,然后返回整个页面给浏览器
<a name="tWWX1"></a>
### @Controller返回json(@Controller和@ResponseBody)

- @Controller+@ResponseBody  返回Json字符串
```java
package com.tedu.springb.controller;

import java.util.ArrayList;
import java.util.List;

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

//@Controller+@ResponseBody  返回Json字符串
@Controller
public class UseController {
    @RequestMapping("/backJson")
    @ResponseBody
    public ArrayList<Item> backJson(){
        ArrayList<Item> itemList = new ArrayList<Item>();
        Item item1 = new Item("oppi", 66);
        Item item2 = new Item("mate10", 88);
        itemList.add(item1);
        itemList.add(item2);
        //SpringMVC自动调用Jackson框架处理对象数组,返回
        return itemList;
    }
}

@Controller与@RestController比较

  • 修饰的类都是唯一实例对象(单例模式),都可以在浏览器上访问类里方法
  • @RestController注解相当于是@Controller注解 + @ResponseBody 合在一起的作用

    • 如果用@RestController注解,无法返回jsp、html,视图解析器ModelAndView也不起作用,只能返回Return里的内容,并自动调用Jackson框架处理为Json字符串返回
    • 如果是@Controller注解,那么加上视图解析器ModelAndView就可以返回jsp、html页面. 如果是在@Controller注解的基础上返回json字符串、xml,那么就需要在指定的方法上加上@ResponseBody注解

      jsp与vue区别

  • 新技术

    • 使用vue,浏览器先请求html,网页加载完之后,再用axios发请求,浏览器请求的数据以json的形式返回给浏览器渲染,用数据绑定把数据显示在网页上。这种方式大大减轻了服务器的处理压力。分清了服务器处理数据,浏览器渲染数据二者工作区别。
  • 老技术前后不分
    • 老技术是把浏览器请求的数据 在服务器上渲染到页面上,然后返回处理好的的jsp、html页面给浏览器

image.png

状态码

  • 404:你找的资源不存在
    • 原因是地址写错了
    • 服务器没有启动
    • 新加的方法没有生效
    • 地址写错了
  • 500:服务器处理失败,抛出异常
  • 302:重定向状态码
  • 200:服务器处理成功,一般用于POST和GET请求

跳转

重定向

  • 重定向返回的是页面,跳转到页面,用@Controller
  • 重定向浏览器的地址栏变为 之后 的地址
  • 重定向状态码 302

  • 浏览器请求,服务器会告诉浏览器改变的新地址,然后浏览器再次发送请求,请求新的地址 ```java package com.tedu.springb.controller;

//重定向返回的是页面,用@Controller @Controller public class UseController { @RequestMapping(“/nextAddr”) public String nextAddr() { return “redirect:http://www.baidu.com“;

}

}

<a name="OTVEd"></a>
### 转发

- 转发后浏览器地址栏还是原来的地址。所以转发前请求的参数在转发后仍然可以读取到,loginByNamePwd里的name,pwd参数会获得loginByCode 的name,pwd参数值

![image.png](https://cdn.nlark.com/yuque/0/2021/png/358364/1610854184552-52cf9b3f-c7f7-4544-9187-4f9f7627fa08.png#align=left&display=inline&height=297&margin=%5Bobject%20Object%5D&name=image.png&originHeight=297&originWidth=589&size=19729&status=done&style=none&width=589)
```java
package com.tedu.springb.controller;

//转发返回的是页面,用@Controller
@Controller
public class UseController {
    //第一输入用户名和密码
    @RequestMapping("/ByNamePwd")
    //注意:返回的是字符串,加上注解    @ResponseBody
    @ResponseBody
    public String loginByNamePwd(String name,String pwd) {
        return "登录成功";
    }
    //再次登录时,还要输入验证码
    @RequestMapping("/Bycode")
    public String loginByCode(String name,String pwd,String code) {
        return "forward:/ByNamePwd";
    }
}

重定向redirect和转发forward的区别

1, 重定向浏览器地址栏显示新的地址,转发地址栏不变
2, 重定向可以重定向别的网站,转发只能转发到本网站中的方法。

RESTFul架构

  • RESTFul要求通过url传输数据
  • @PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上形成RUSTFul形式,这将是未来的发展趋势。它更加简洁,安全。强化URL GET访问方式。
  • 普通传递参数的方法是 url?name=iu&pwd=18
  • RESTFul传递参数 url/iu/18 ```java package com.tedu.springb.controller;

@RestController public class UseController { //RESTFul参数路径 @RequestMapping(“/select/{name}/{pwd}”) //@PathVariable用于将请求URL中的 模板变量 映射到 功能处理方法的参数上 形成RUSTFul形式 public String select(@PathVariable String name,@PathVariable String pwd) { return “查找”+name+”,”+pwd+”success”; } } ```