• SpringMvc的第二天


    目录

    一、请求参数的封装

     1.简单数据类型

      1.1 同名  

      1.2 不同名

     2.自定义pojo类型

     3.数组   

       3.1同名

      3.2不同名

     4.集合

    二、Post请求的中文乱码问题

    1.设置方式

    三、自定义类型转换器

    3.1 注解

    3.2 自定义类型转换

       1.创建自定义转换器实现 Converter接口

    2.将自动类型转换器交给spring管理

    3.将自定义类型注入到类型转换工厂中

    4.前端控制器使用最新的类型转换工厂

     四、静态资源的处理

    第一种方法  采用类型映射让资源路径不仅如此前端控制器  (不推荐使用)

    第二种方法: 可以在springmvc中声明某些资源是静态资源

    第三种  default-servlet-handler 

     五、异步请求的定义方式

    1.搭建异步请求的环境

    2.异步请求的定义方式

      2.1 无返回值

      2.2 返回String

      2.3 返回自定义类型或者hashmap

      2.4返回集合

      2.5  @RequestBody将json格式的字符串封装为自定义类型

     扩展

    六、Resful风格的请求



    一、请求参数的封装

     1.简单数据类型

      1.1 同名  

    同名:在handler的形参列表中定义一个形参,形参名称和请求参数的名称一致,在执行handler时,请求参数参数会自动封装到形参中,并且可以进行默认的类型转化 (类型转化出现异常---即形参为Integer请求参数是String 就会发生类型转换异常)

    1. //简单数据类型的封装 同名的---形参和请求参数的名称相同
    2. @RequestMapping(value = "/test10")
    3. public ModelAndView test10(String name,Integer age,Integer sex) {
    4. ModelAndView model=new ModelAndView("/test.jsp");
    5. model.addObject("name", name);
    6. model.addObject("name1", age);
    7. model.addObject("name2", sex);
    8. return model;
    9. }

      1.2 不同名

    请求参数的名称和形参的名称不一致的时候,使用参数级别的注解  @RequestParam(指定映射规则)

    1. //简单数据类型的封装 不同名 --使用参数级别的注解@RequestParam
    2. //属性 name:用于指定请求参数的名称
    3. //required :当前参数是否必填
    4. //defaultValue 代表如果required=true,设置了默认值后,请求参数可以不传递 --采取默认值
    5. @RequestMapping(value = "/test11")
    6. public ModelAndView test11(@RequestParam(name="Username",required = true,defaultValue = "moren")String name,Integer age,Integer sex) {
    7. ModelAndView model=new ModelAndView("/test.jsp");
    8. model.addObject("name", name);
    9. model.addObject("name1", age);
    10. model.addObject("name2", sex);
    11. return model;
    12. }

    优缺点 :1.优化了servlet的请求参数获取方式  (无序使用req.getParameter(name)获取)

                    2.如果请求参数过多的话,方法的形参列表过长

    因此出现了自定义的pojo类型

     2.自定义pojo类型

       springmvc会自动根据形参中自定义类型的参数的属性名和请求参数名进行封装(如果请求参数名称和形参中某个属性名称一致,自动进行封装) 和形参名没有任何关系

    1. //自定义pojo的封装
    2. //请求参数与形参的名称无关 ,只有 形参对应的属性名有关 属性名相同进行封装 不同为默认值
    3. @RequestMapping(value = "/test12")
    4. //注意这个如果请求参数没有输入 user和role对象是不为空 只是它们的属性为默认值----优点:我们不需要进行判断是否为空
    5. public String test12(User user ,Role role ,ModelAndView model) {
    6. return "/test.jsp";
    7. }

    注意:

    如果请求参数和形参中所有的属性名都不一致,自定义类型的属性不为null,但是成员变量都为默认值   

    即 上面例子中  user  和role 对象不为null   但是它们两个的成员变量为默认值

     3.数组
       

    类似于 request.getParameterValues("属性名")

    将同名的请求参数封装为数组,并自动进行类型转换。

    在形参列表中定义一个数组类型的参数

       3.1同名

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html>
    4. <html>
    5. <head>
    6. <meta charset="ISO-8859-1">
    7. <title>Insert title heretitle>
    8. head>
    9. <body>
    10. <form action="a/test13" method="post">
    11. <input type="checkbox" name="ids" value="1">1
    12. <input type="checkbox" name="ids" value="2">2
    13. <input type="checkbox" name="ids" value="3">3
    14. <input type="checkbox" name="ids" value="4">4
    15. <input type="checkbox" name="ids" value="5">5
    16. <input type="checkbox" name="ids" value="6">6
    17. <input type="submit" value="提交">
    18. form>
    19. body>
    20. html>
    1. @RequestMapping(value = "/test13" ,method = RequestMethod.POST)
    2. public String test13(Integer[] ids) {
    3. for (Integer integer : ids) {
    4. System.out.println(integer);
    5. }
    6. return "/test.jsp";
    7. }

      3.2不同名

    1. @RequestMapping(value = "/test13" ,method = RequestMethod.POST)
    2.         public String test13(@RequestParam(name="ids") Integer[] idss)  {   
    3.             for (Integer integer : ids) {
    4.                 System.out.println(integer);
    5.             }
    6.             return "/test.jsp";
    7.         }

     4.集合

    作用将请求参数封装为扩展类,主要用于复杂表单的构建(动态表单)

    将扩展类做为形参的参数

     

     

    1. package com.sofwin.pojo;
    2. import java.util.Date;
    3. import java.util.List;
    4. import org.springframework.format.annotation.DateTimeFormat;
    5. import com.fasterxml.jackson.annotation.JsonIgnore;
    6. import com.fasterxml.jackson.annotation.JsonProperty;
    7. public class User {
    8. private Integer id;
    9. // @JsonIgnore //忽略系列化
    10. @JsonProperty(value = "name") //修改序列化字段 即 返回的就是name=。。。。
    11. private String userName ;
    12. private Integer userAge;
    13. // @DateTimeFormat(pattern = "yyyy.MM.ss")
    14. private Date date;
    15. public Date getDate() {
    16. return date;
    17. }
    18. public void setDate(Date date) {
    19. this.date = date;
    20. }
    21. private List roles;
    22. public List getRoles() {
    23. return roles;
    24. }
    25. public void setRoles(List roles) {
    26. this.roles = roles;
    27. }
    28. public Integer getId() {
    29. return id;
    30. }
    31. public void setId(Integer id) {
    32. this.id = id;
    33. }
    34. public String getUserName() {
    35. return userName;
    36. }
    37. public void setUserName(String userName) {
    38. this.userName = userName;
    39. }
    40. public Integer getUserAge() {
    41. return userAge;
    42. }
    43. public void setUserAge(Integer userAge) {
    44. this.userAge = userAge;
    45. }
    46. }

    1. package com.sofwin.pojo;
    2. public class Role {
    3. private Integer id;
    4. private String roleName ;
    5. private Integer roleAge;
    6. public Integer getId() {
    7. return id;
    8. }
    9. public void setId(Integer id) {
    10. this.id = id;
    11. }
    12. public String getRoleName() {
    13. return roleName;
    14. }
    15. public void setRoleName(String roleName) {
    16. this.roleName = roleName;
    17. }
    18. public Integer getRoleAge() {
    19. return roleAge;
    20. }
    21. public void setRoleAge(Integer roleAge) {
    22. this.roleAge = roleAge;
    23. }
    24. }
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html>
    4. <html>
    5. <head>
    6. <meta charset="UTF-8">
    7. <title>Insert title heretitle>
    8. head>
    9. <body>
    10. <div><h1>用户数据h1>div>
    11. <div>
    12. <form action="a/test14" method="post">
    13. <div>用户名称<input type="text" name="userName" /> 用户年龄<input type="text" name="userAge" />div>
    14. <div style="float:right"> <input type="button" onclick="addRole()" value="增加权限"/>div>
    15. <div id="roleDate">div>
    16. <div><input type="submit" value="保存"/>div>
    17. form>
    18. div>
    19. body>
    20. <script type="text/javascript">
    21. var index=0; //设置索引
    22. function addRole() {
    23. var info=document.getElementById("roleDate").innerHTML;
    24. info+='
      角色名称'].roleName"/>'
    25. document.getElementById("roleDate").innerHTML=info;
    26. index++;
    27. }
    28. script>
    29. html>

    1. //集合
    2. @RequestMapping(value = "/test14" ,method = RequestMethod.POST)
    3. public String test14(User user) {
    4. return "/test.jsp";
    5. }

     集合请求参数的名称为  集合的属性的属性名[索引].属性名

    即例子中的   roles[0].roleName

    二、Post请求的中文乱码问题

    中文乱码,我们是设置编码是UTF-8,在之前的web我们是自己创建的过滤器对所有的请求进行过滤,进行编码的设置

    springmvc给我们提供了过滤器,我们直接使用即可

    提过的过滤器是在spring-web的jar包中的一个类

     

     

    1.设置方式

    在web.xml中设置

    1. <filter>
    2. <filter-name>postEncodingfilter-name>
    3. <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    4. <init-param>
    5. <param-name>encodingparam-name>
    6. <param-value>UTF-8param-value>
    7. init-param>
    8. <init-param>
    9. <param-name>forceRequestEncodingparam-name>
    10. <param-value>trueparam-value>
    11. init-param>
    12. <init-param>
    13. <param-name>forceResponseEncodingparam-name>
    14. <param-value>trueparam-value>
    15. init-param>
    16. filter>
    17. <filter-mapping>
    18. <filter-name>postEncodingfilter-name>
    19. <url-pattern>/*url-pattern>
    20. filter-mapping>

    这样设置就可以解决中文乱码的问题

    三、自定义类型转换器

    springmvc提供了内置的类型转换器 

    其中Date 是yyyy/MM/ss  但是其他的例如-或者.都是不行的 ,因此我们可以自定义设置

    3.1 注解

        开启mvc的注解驱动(要引入mvc的约束)

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns:context="http://www.springframework.org/schema/context"
    4. xmlns:aop="http://www.springframework.org/schema/aop"
    5. xmlns:mvc="http://www.springframework.org/schema/mvc"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans
    7. https://www.springframework.org/schema/beans/spring-beans.xsd
    8. http://www.springframework.org/schema/context
    9. https://www.springframework.org/schema/context/spring-context.xsd
    10. http://www.springframework.org/schema/aop
    11. https://www.springframework.org/schema/aop/spring-aop.xsd
    12. http://www.springframework.org/schema/mvc
    13. https://www.springframework.org/schema/mvc/spring-mvc.xsd
    14. ">
    15. <context:component-scan base-package="com.sofwin">context:component-scan>
    16. <mvc:annotation-driven>mvc:annotation-driven>
    17. beans>

    使用@DateTimeFormat(pattern="yyyy-MM-dd")

    1. @RequestMapping(value = "/test15" )
    2. public String test15(User user) {
    3. return "/test.jsp";
    4. }

    这样设置完毕后 请求参数是String,就会自动转换为date类型

    3.2 自定义类型转换

       1.创建自定义转换器实现 Converter接口

    1. package com.sofwin.converter;
    2. import java.text.ParseException;
    3. import java.text.SimpleDateFormat;
    4. import java.util.Date;
    5. import java.util.logging.SimpleFormatter;
    6. import org.springframework.core.convert.converter.Converter;
    7. // s代表的传入参数的类型 T 表示要转换的类型
    8. public class MyDateConverter implements Converter {
    9. @Override
    10. public Date convert(String date) {
    11. SimpleDateFormat sdf=new SimpleDateFormat("yyyy=MM=ss");
    12. try {
    13. Date flag = sdf.parse(date);
    14. return flag;
    15. } catch (ParseException e) {
    16. // TODO Auto-generated catch block
    17. e.printStackTrace();
    18. }
    19. return null;
    20. }
    21. }

    2.将自动类型转换器交给spring管理

    1. <bean id="myDateConverter" class="com.sofwin.converter.MyDateConverter">bean>

    3.将自定义类型注入到类型转换工厂中

    1. <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
    2. <property name="converters">
    3. <set>
    4. <ref bean="myDateConverter"/>
    5. set>
    6. property>
    7. bean>

    4.前端控制器使用最新的类型转换工厂

    mvc:annotation-driven conversion-service="conversionServiceFactoryBean">mvc:annotation-driven>

    测试

    1. @RequestMapping(value = "/test16" )
    2. public String test16(Date date) {
    3. return "/test.jsp";
    4. }

     

     

     四、静态资源的处理

    因为在这个xml中设置了/ 代表处理jsp其他都要进入到前端控制器,但是在前端控制器中找不到js的映射 因此会无法使用js  或者是css  image等

    因此我们要设置让这些的静态资源不进入到前端控制器中

    第一种方法  采用类型映射让资源路径不仅如此前端控制器  (不推荐使用)

    第二种方法: 可以在springmvc中声明某些资源是静态资源

    1. <mvc:resources location="/css/" mapping="/css/**">mvc:resources>
    2. <mvc:resources location="/js/" mapping="/js/**">mvc:resources>

    第三种  default-servlet-handler 

     <mvc:default-servlet-handler />

     五、异步请求的定义方式

    @RestController     

     类级别的组合注解

    就相当于两个注解的组合

    @Controller  和@ResponseBody  

    这两个注解的意义: 声明该类的所有请求都是异步请求

    同步请求和异步请求两者之间的区别

    同步请求是返回的视图

    异步请求是返回的数据   

    1.搭建异步请求的环境

    springmvc默认支持的异步请求中数据的格式转换jackson,来将数据序列化为json格式

    json格式要添加的三个依赖

    jackson-core

    jackson-databind

    jackson-annotation

    2.异步请求的定义方式

      2.1 无返回值

    1. //1.无返回值
    2. //@ResponseBody 声明这个方法是异步请求
    3. //同步请求 返回的是视图 异步请求返回的数据 可以是json 可以是字符串 等等
    4. @ResponseBody
    5. @GetMapping("/test01")
    6. public void test01(HttpServletResponse response) throws IOException {
    7. PrintWriter writer = response.getWriter();
    8. writer.write("/test01/jsp");
    9. }

    结果是

      2.2 返回String

    1. //2.返回String
    2. @ResponseBody
    3. @GetMapping("/test02")
    4. public String test02() {
    5. return "王五";
    6. }

      2.3 返回自定义类型或者hashmap

    1. //3.返回自定义类型 异步请求返回的是json对象,springmvc根据jackson将结果自动进行json序列化
    2. //这里要放三个json-jar包 jsckson-core jsckson-databind jsckson-annotations
    3. @ResponseBody
    4. @GetMapping("/test03")
    5. public User test03(User user) {
    6. return user;
    7. }

      2.4返回集合

    1. //4.返回集合
    2. @ResponseBody
    3. @GetMapping("/test04")
    4. public List test04() {
    5. List list =new ArrayList();
    6. for(int i=1;i<100;i++) {
    7. User user =new User();
    8. user.setId(i);
    9. user.setUserName("sofwin"+i);
    10. list.add(user);
    11. }
    12. return list;
    13. }

      2.5  @RequestBody将json格式的字符串封装为自定义类型

      封装的原则按照属性名进行封装 
    注意 要满足以上3点要求
          1.请求必须使用POST请求
          2.请求参数必须是json格式的字符串(不能是json对象   我们是用JSON.stringify()将json对象转换为字符串)
         3.contentType必须是application/json
    是参数级别的注解,将json格式的字符串封装为自定义类型

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html>
    4. <html>
    5. <head>
    6. <meta charset="UTF-8">
    7. <script src="js/jquery-3.6.0.js">script>
    8. <link rel="stylesheet" href="css/css1.css">
    9. <title>Insert title heretitle>
    10. head>
    11. <body>
    12. <input type="button" onclick="bind()" value="异步请求"/>
    13. body>
    14. <script type="text/javascript">
    15. function bind() {
    16. $.ajax({
    17. url:"test06?UserName=zhangsan&userAge=11",
    18. type:"post",
    19. dataType:"json",
    20. success:function(ret){
    21. alert(ret);
    22. //JSON要大写
    23. alert(JSON.stringify(ret));
    24. $.ajax({
    25. url:"test07",
    26. type:"post",
    27. data:JSON.stringify(ret),
    28. dataType:"json",
    29. contentType:"application/json",
    30. success:function(ret){
    31. alert(JSON.stringify(ret));
    32. }
    33. })
    34. }
    35. })
    36. }
    37. script>
    38. html>
    1. @ResponseBody
    2. @PostMapping("/test06")
    3. public User test06( User user) {
    4. return user;
    5. }
    6. @ResponseBody
    7. @PostMapping("/test07")
    8. public User test07(@RequestBody User user) {
    9. return user;
    10. }

    实例

     

     扩展

       @JsonLgnore  忽略序列化 

     这样设置就不会显示username了

    1. @ResponseBody
    2. @GetMapping("/test03")
    3. public User test03(User user) {
    4. return user;
    5. }

    @JsonProperty 修改序列化字段的名称

     

    1. @ResponseBody
    2. @GetMapping("/test03")
    3. public User test03(User user) {
    4. return user;
    5. }

    六、Resful风格的请求

    RESTFUL 是一种网络应用程序的设计风格和开发方
    式,基于 HTTP ,可以使用 XML 格式定义或 JSON 格式定
    义。 RESTFUL 适用于移动互联网厂商作为业务接口的场
    景,实现第三方 OTT 调用移动网络资源的功能,动作类
    型为新增、变更、删除所调用资源

     @PathVariable  

    用于声明路径变量,是一个参数级别的注解,接受请求参数,并将接受请求参数作为请求地址

    比如京东将商品编号作为请求地址,商品编号为动态的,请求地址也是动态的

    1. //Resful风格
    2. @ResponseBody
    3. @GetMapping("/info/{name}")
    4. public String test07(@PathVariable String name) {
    5. return name;
    6. }

    输入wentao ,页面返回wentao 

     输入zhangsan ,页面返回zhangsan

     

  • 相关阅读:
    Vue2 06 插槽 slot
    基于Cplex的人员排班问题建模求解(JavaAPI)
    企业电子招投标采购系统——功能模块&功能描述+数字化采购管理 采购招投标
    文件系统类数据读取与保存HBase_大数据培训
    如何理解Spring的IOC和AOP
    Python异步爬虫(aiohttp版)
    Docker容器自启动
    【代码随想录】-栈和队列专栏(Java)
    基础题--数组
    8月20日计算机视觉理论学习笔记——神经网络与BP算法
  • 原文地址:https://blog.csdn.net/weixin_52574640/article/details/125873409