zoukankan      html  css  js  c++  java
  • SpringMVC-@RequestMapping、@PathVariable、Rest、POJO封装、乱码问题

    @RequestMapping

    1. 当标注在方法上的时候,代表的是此方法的请求地址

      @RequestMapping("/hello")
      public void hello(){	
      	xxxxxx
      	return "hellodemo";
      }
      

      此时我们访问localhost/hello 请求就可以跳转到我们拼接好的 WEB/INF/jsp/hellodemo.jsp

    2. 当标注在类上时,为这个类的所有方法的请求地址指定一个基准路径(父路径)

      @RequestMapping("/test")
      @Controller
      public void helloController{
      	@RequestMapping("/hello")
          public void hello(){	
              xxxxxx
              return "hellodemo";
          }
      }
      

      那么此时我们如果想访问hello请求,则需要地址前加上test,即localhost/test/hello

    3. method:限定请求方式

      HTTP协议中所有的请求有 GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE

      当然默认是全部接受

      @RequestMapping(value = "/demo",method = RequestMethod.POST)
          public String demo01(){
              return "demo";
          }
      

      那么此时我的demo请求只允许接受POST请求方式,其他的请求都不接受

    4. params:规定请求参数

      1. params={"useranme"} :发送请求的时候必须带username,不带404
      2. !params={"useranme"} :发送请求的时候必须不带username,带了404
      3. params={"useranme!=123"} :发送请求的时候username的值必须不是123
      4. params={"useranme=123","pwd","!age"} :发送请求的时候username的值必须是123,必须有pwd的值,不能有age的值
    5. headers:规定请求头,同params一样能写表达式

      headers={"User-Agent=Firfox"}:允许火狐访问,不允许其他浏览器访问

      通过浏览器netwrok中获取User-Agent来获取请求头

    6. consumes:只接受内容类型是哪种的请求,规定请求头中的Content-Type

    7. produces:告诉浏览器返回的内容类型是什么,给响应头中加上Content-Type

    8. Ant风格的url

      这是精确匹配 /test01

      @RequestMapping("/test01")
          public void test01(){	
              xxxxxx
              return "test01";
          }
      
      

      我们通过?来模糊匹配 即/test03 /test04 都可以匹配到test02方法中,但只能匹配一位,不可以多写或少写

      @RequestMapping("/test0?")
          public void test02(){	
              xxxxxx
              return "test02";
          }
      

      我们通过*匹配任意多个字符 /test0123

      @RequestMapping("/test0*")
          public void test02(){	
              xxxxxx
              return "test02";
          }
      

      通过*模糊路径 /a123456/test02 , /a12/test02

      @RequestMapping("a*/test02")
          public void test02(){	
              xxxxxx
              return "test02";
          }
      

    @PathVariable

    比如我们此刻的请求是 /user/admin 我们可以直接指定,但假如我还有/user/list /user/name就很麻烦了

    所以我们可以通过{id} 来占位符,然后通过方法String id 传入值,通过@PathVariable来获取这个id值

    @Controller
    public class RequestMappingTest {
        @RequestMapping("/user/{id}")
        public String demo(@PathVariable("id")String id){
            System.out.println(id);
            return "hello";
        }
    }
    

    Rest

    Rest介绍

    Rest:系统希望以非常简洁的URL地址来发请求;
    用请求方式来区分对一个资源的增删改查

    /getBook?id=1:查询图书
    /deleteBook?id=2:删除图书

    Rest:/资源/资源标识符
    /book/1 :GET方式请求---查询1号图书
    /book/1 : PUT方式请求---更新1号图书
    /book/1 : POST方式请求---添加1号图书
    /book/1 : DELETE方式请求---删除1号图书

    问题:从页面上只能发起get和post请求

    Rest环境

    在BookController有四个方法

    @Controller
    public class BookController {
    
        @RequestMapping(value = "/book/{id}",method = RequestMethod.GET)
        public String getBook(@PathVariable("id")String id){
            System.out.println("你查询了"+id+"图书");
            return "hello";
        }
        @RequestMapping(value = "/book/{id}",method = RequestMethod.DELETE)
        public String delBook(@PathVariable("id")Integer bid){
            System.out.println("你删除了"+bid+"图书");
            return "hello";
        }
        @RequestMapping(value = "/book/{id}",method = RequestMethod.PUT)
        public String updateBook(@PathVariable("id")Integer bid){
            System.out.println("你更新了"+bid+"图书");
            return "hello";
        }
        @RequestMapping(value = "/book",method = RequestMethod.POST)
        public String addBook(){
            System.out.println("你添加了图书");
            return "hello";
        }
    
    }
    
    <a href="book/1">查询图书</a><br>
    <form action="book" method="post">
      <input type="submit" value="添加1号图书">
    </form>
    <a href="book/1">删除图书</a><br>
    <a href="book/1">更新图书</a><br>
    

    但是此刻我们无法使用put和delete形式的请求

    Rest的CRUD

    1.springMVC中有一个Filter,可以把普通的请求转换成规定形式的请求,配置这个filter

    在web.xml中配置filter

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    2.创建一个post表单,表单中携带一个_method的参数,这个_method的值就是DELETE、PUT

    <a href="book/1">查询图书</a><br>
    <form action="book" method="post">
      <input type="submit" value="添加1号图书">
    </form>
    <form action="book/1" method="post">
      <input name="_method" value="delete">
      <input type="submit" value="删除1号图书">
    </form>
    <form action="book/1" method="post">
      <input name="_method" value="put">
      <input type="submit" value="更新1号图书">
    </form>
    

    注意高版本tomcat会提示HTTP Status 405 – 方法不允许
    在我们返回的jsp页面上加isErrorPage="true"

    <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%>
    

    获取请求带来的信息

    默认方式获取请求参数

    直接给方法入参上写一个和请求参数名相同的变量

    <a href="hello?name=tomcat">hello</a>
    

    在这里我们请求的参数是 name
    所以我们在方法的参数上定义String name

    @RequestMapping("/hello")
    public String handle01(String name){
        System.out.println("handle01"+name);
        return "hello";
    }
    

    结果 handle01tomcat,如果没参数就是handle01null

    @RequestParam

    @RequestParam:获取请求参数,参数默认是必须带的,
    value:指定要获取的参数key
    require:是否必须带
    defaultvalue:默认值设置

    @RequestMapping("/hello")
    public String handle01(@RequestParam("name")String username){
        System.out.println("handle01"+username);
        return "hello";
    }
    

    @RequestParam("name")String username其实就是
    username = request.getParameter("name")

    @PathVariable和@RequestParam的区别
    @PathVariable是获取路径中的值 比如 /book/{user}?user=xxx
    它获取的是?前面路径中的user值
    @RequestParam是获取的传入参数的值,即user=xxx中user的值

    @RequestHeader

    获取请求头中某个key的值
    value:指定要获取的参数key
    require:是否必须带
    defaultvalue:默认值设置

    @RequestMapping("/hello")
    public String handle01(@RequestParam("name")String username, @RequestHeader("User-Agent")String useragent){
        System.out.println("handle01"+username);
        System.out.println("User-Agent"+useragent);
        return "hello";
    }
    

    @RequestHeader("User-Agent")String useragent获取浏览器头信息
    useragent = request.getHeader("User-Agent")

    @CookieValue

    @RequestMapping("/hello")
    public String handle01(@RequestParam("name")String username,
                           @RequestHeader("User-Agent")String useragent,
                           @CookieValue("JSESSIONID")String jid){
        System.out.println("handle01"+username);
        System.out.println("User-Agent"+useragent);
        System.out.println("JsessionId是"+jid);
        return "hello";
    }
    

    POJO自动封装

    页面

    <form action="book" method="post">
      书名:<input type="text" name="bookName">
      作者:<input type="text" name="author">
      价格:<input type="text" name="price">
      库存:<input type="text" name="stock">
      销量:<input type="text" name="sales">
      <input type="submit" value="提交">
    </form>
    

    pojo类Book

    public class Book {
        private String bookName;
        private String author;
        private double price;
        private Integer stock;
        private Integer sales;
        有参无参get/set和tostring....
    

    controller

    @RequestMapping("/book")
    public String addBook(Book book){
        System.out.println(book);
        return "hello";
    }
    

    如果我嗯的请求参数是一个POJO:
    Spring会自动为这个POJO进行赋值
    1.将POJO中的每一个属性,从request参数中尝试获取出来,并封装即可
    2.还可以封装级联属性:属性.属性

    比如name=address.provice

    使用原生API

    SpringMVC可以在参数上写原生API

    • HttpServletRequest
    • HttpSession
    • HttpResponse
    • Locale:国际化有关的区域信息对象
    • InputStream、OutputStream、Reader、Writer
    @RequestMapping("/handle03")
    public String handle03(HttpSession session, HttpServletRequest request){
        request.setAttribute("reqParam","我是请求域中的");
        session.setAttribute("sessionParam","我是session域中的");
        return "hello";
    }
    

    hello.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    请求:${requestScope.reqParam}
    session:${sessionScope.sessionParam}
    </body>
    </html>
    

    乱码

    在xml中配置SpringMVC的乱码过滤器

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--encoding:指定解决POST请求乱码-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <!--顺手解决响应乱码-->
            <param-name>forcEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  • 相关阅读:
    maven复制依赖到文件夹
    spring security 5.x 原理
    spring security 5.x oauth2 client [invalid_request]
    spring security 5.x Provider
    Spring Security 5.x Invalid Authorization Grant Type (password) for Client Registration with Id: reader
    idea terminal npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
    git 删除已提交多余文件
    unresolved dependency "org.springframework.security.spring-security-web.jar"
    spring security 5 session管理
    java web项目中的jsessionID的作用
  • 原文地址:https://www.cnblogs.com/pengcode/p/12747514.html
Copyright © 2011-2022 走看看