SpringMVC中map类型参数接收和乱码问题以及数据传递机制

1. SpringMVC中map类型参数接收

在CollectionVO对象中定义一个map<String, String>类型的名为maps的成员变量,并提供get、set方法

// 自定义Vo对象
public class CollectionVO {

    private List<String> lists;

    private Map<String, String> maps;

    public Map<String, String> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }

    public List<String> getLists() {
        return lists;
    }

    public void setLists(List<String> lists) {
        this.lists = lists;
    }
}

测试map类型参数的接收

在这里插入图片描述

在这里插入图片描述

使用Tomcat8部署项目时,有接口会报400错误,后端提示在请求目标中找到无效字符有效字符在RFC 7230和RFC 3986中定义
tomcat在8.5版本之后对请求的url的数值做了限制,如果url中有其他特殊符号需要进行配置,否则tomcat无法处理该请求。

在这里插入图片描述

当我们在插入map的时候例如:

http://localhost:9999/springmvc_day1/param/test3?maps['aaa']=111&maps['bbb']=222&maps['ccc']=333

在地址栏会将’单引号解析为%

tomcat高版本严格按照RFC 3986规范解析地址。该规范只允许包含 a-zA-Z 0-9 - _ . ~ 以及所有保留字符 ! * ’ ( ) ; : @ & = + $ , / ? # [ ]没有%

所以我们要在配置文件中进行修改

在这里插入图片描述

relaxedPathChars="|{}[],%" relaxedQueryChars="|{}[],%"

在这里插入图片描述

学习于:在请求目标中找到无效字符。有效字符在RFC 7230和RFC 3986中定义

这样之后我们地址栏输入:

http://localhost:9999/springmvc_day1/param/test3?maps['aaa']=111&maps['bbb']=222&maps['ccc']=333

就会打印出:

k = aaa v = 111
k = bbb V = 222
k = ccc v = 333

打印出了正确的结果

2. springmvc在接收请求参数时中文乱码问题解决方案

接收表单

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试参数接收</title>
</head>
<body>

    <h1>测试对象和零散对象接收</h1>
    <form action="" method="get">
        用户id:<input type="text" name="id"> <br>
        用户name:<input type="text" name="name"> <br>
        用户age:<input type="text" name="age"> <br>
        用户bir:<input type="text" name="bir"> <br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

# springmvc在接收post请求参数时中文乱码问题解决方案

1. 出现乱码的两种请求方式的解决方案

	a. GET方式的请求出现乱码
	
		tomcat8.x版本以前 默认使用server.xml 中URIEncoding="iso-8559-1" 编码不是utf-8 出现中文乱码
		
		tomcat8.x版本以后 默认使用server.xml 中URIEncoding="UTF-8"
		
2. 在springmvc中post方式中文乱码解决方案

	说明:在springmvc中默认没有对post方式请求进行任何编码处理,所以直接接收post方式请求会出现中文乱码
	
	a. 解决方案
		自定义filter	request,response对象编码
		
	b. 使用springmvc提供好的编码filter	CharacterEncodingFilter

2.1 解决get请求出现的中文乱码

表单:

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试参数接收</title>
</head>
<body>

    <h1>测试对象和零散对象接收</h1>
    <form action="${pageContext.request.contextPath}/param/test1" method="get">
        用户id:<input type="text" name="id"> <br>
        用户name:<input type="text" name="name"> <br>
        用户age:<input type="text" name="age"> <br>
        用户bir:<input type="text" name="bir"> <br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

如果使用的是旧版的idea,并且使用了tomcat8.x版本甚至更新默认使用server.xml 中URIEncoding="UTF-8"所以不用解决

如果是新版本的idea,2021.x的新版本idea,不再认可直接从文件中编辑参数

因此我们这样修改编码格式:

在这里插入图片描述

在这里插入图片描述

测试:

/**
 * 用来测试参数接收的Controller
 */
@Controller
@RequestMapping("param")
public class ParamController {
    /**
     * 用来测试对象类型的参数接收
     * 接收对象类型:也是直接将要接受的对象作为控制器方法参数声明
     * 注意:springmvc封装对象时直接根据传递参数key与对象中属性名一致自动封装对象
     * url: http://localhost:9999/springmvc_day1/param/test1?id=21&name=zhangsan&age=23&bir=2012/12/12
     * form:
     *      input   name="id"
     *      input   name="name"
     *      input   name="age"
     *      input   name="bir"
     */
    @RequestMapping("test1")
    public String test1(User user, String name){
        System.out.println("name = " + name);
        System.out.println("user = " + user);
        return "index";
    }
}

在这里插入图片描述

在这里插入图片描述

其实上面这个方法就已经解决了下面的post请求出现的中文乱码问题,但是我们还是要学一学另外的处理方式。

2.2 解决post请求出现的中文乱码

测试类:

/**
 * 用来测试参数接收的Controller
 */
@Controller
@RequestMapping("param")
public class ParamController {
    /**
     * 用来测试对象类型的参数接收
     * 接收对象类型:也是直接将要接受的对象作为控制器方法参数声明
     * 注意:springmvc封装对象时直接根据传递参数key与对象中属性名一致自动封装对象
     * url: http://localhost:9999/springmvc_day1/param/test1?id=21&name=zhangsan&age=23&bir=2012/12/12
     * form:
     *      input   name="id"
     *      input   name="name"
     *      input   name="age"
     *      input   name="bir"
     */
    @RequestMapping("test1")
    public String test1(User user, String name){
        System.out.println("name = " + name);
        System.out.println("user = " + user);
        return "index";
    }
}

表单:

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试参数接收</title>
</head>
<body>

    <h1>测试对象和零散对象接收</h1>
    <form action="${pageContext.request.contextPath}/param/test1" method="post">
        用户id:<input type="text" name="id"> <br>
        用户name:<input type="text" name="name"> <br>
        用户age:<input type="text" name="age"> <br>
        用户bir:<input type="text" name="bir"> <br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

  • 使用自定义的filter

定义一个过滤类,专门用来解决中文乱码问题:


// 自定义编码filter
public class CharacterEncodingFilter implements Filter {

    private String encoding;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.encoding = filterConfig.getInitParameter("encoding");// 读取局部初始化参数
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding(encoding);   // 设置请求的编码为UTF-8
        servletResponse.setCharacterEncoding(encoding);  // 设置响应的编码为UTF-8
        filterChain.doFilter(servletRequest, servletResponse);  // 放行请求
    }

    @Override
    public void destroy() {

    }
}

在这里插入图片描述

在这里插入图片描述

web.xml文件中配置filter

<!--配置自定义的编码filter-->
<filter>
  <filter-name>charset</filter-name>
  <filter-class>com.baizhi.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>	
    <param-value>UTF-8</param-value>		<!--局部初始化参数,这样以后我们想要什么样的编码我们就在这里写就好了-->
  </init-param>
</filter>
<filter-mapping>
  <filter-name>charset</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

在这里插入图片描述

其实这个过滤类谁来写都一样的,所以官方写好了一个过滤类,我们只需要在web.xml文件中配置即可

  • 使用springmvc官方提供好的编码filter

  <!--配置post请求方式中文乱码的Filter-->
  <filter>
    <filter-name>charset</filter-name>
    <filter-class>org.springframework.web.filter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>charset</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

在这里插入图片描述

测试:

在地址栏输入:

http://localhost:9999/springmvc_day1/param/test1

在这里插入图片描述

3. SpringMVC中数据传递机制

springmvc其实是一个控制器,对于一个控制器而言,我们就关注三件事,收集数据调用业务对象流程跳转,其实在调用业务对象跳转流程这两个环节里其实还隐藏了一步,就是数据的传递过程

在这里插入图片描述

# springmvc中数据传递机制

1. 数据传递机制

										 页面如何获取数据					页面如何展示数据
				数据怎么存储?				数据在页面如何获取?				在页面中获取的数据该如何展示?
		
Servlet			request,				  EL表达式						  EL+JSTL标签 展示
				session,
				application
				
Struts2			request,				  EL表达式						  EL+JSTL标签 展示
				session,
				application
				
SpringMVC		request,				  EL表达式						  EL+JSTL标签
				session,
				application	
				
				
2. 存数据具体使用哪种作用域
		跳转方式:
			forward: 一次请求  request作用域|Model(springmvc提供,Model内部封装的就是request,且Model只能用于forward)
			redirect:多次请求  session作用域 application作用域[不推荐] ?"问号"地址栏传递(但是"问号"传递的数据是有限的)
	
3. 如何在springmvc控制器方法中获取request对象,response对象

	// 声明一个HttpServletRequest、HttpServletResponse,会在请求访问控制器这个方法时会自动把当前的请求对象
	// 和响应对象赋值给这两个声明的参数
	public String findAll(HttpServletRequest request, HttpServletResponse response){
		request.getSession();			// 拿到session对象
		request.getServletContext();	// 拿到application对象
	}
	
	注意:直接将request response对象作为控制器方法参数声明即可获取
- Servlet中数据传递机制:

springmvc是一个控制器,这个控制器可以说是基于最早期原始的servlet技术而来的,所以我们先来回顾一下servlet中的
数据处理机制,在servlet中存数据我们得找作用域,所以在整个servlet中我们在做数据传递的过程中,我们其实用的是
request、session、application这样的对象,日后在存储数据时,我们就用这些作用域,那时候我们的页面该如何获取呢,
在servlet我们是通过EL表达式去获取存在作用域中的数据。如果取的是单个数据,EL表达式取出来之后直接展示;如果是一个
集合类型的数据,取出来之后我们要通过EL去获取配合JSTL标签才能展示数据。

- Struts2中数据传递机制

Struts2中存数据的时候其实我们用的也是作用域,request、session、application,只不过struts2有一个特有的机制,
成员变量替换了request作用域,虽然它替换request作用,但它底层操作的也是request对象,所以我们也可以认为,它就是
直接request,Struts2是如何在页面中取数据呢,同样是EL表达式,那在页面中如何去展示数据呢,EL+JSTL标签展示数据。
获取request对象,response对象:
Struts2:ServletActionContext.getRequest(); 	  ServletActionContext.getResponse();		工具类

- springmvc中数据传递机制

其实对于springmvc而言,它作为一个控制器框架,这个控制器框架如果在开发的时候想要被更多的人接受,那它就尽可能做到轻量,
不要让更多的开发人员去花费大量的精力去学它,所以springmvc也沿用了原始的servlet或struts2中的数据处理机制,也就是在
springmvc中数据处理机制没变,存数据还是request、session、application,存数据还是找作用域,取数据还是用EL表达式,
取出来的数据如果是多个,同样用EL+JSTL标签去展示。如果是单个数据,EL取出来直接就展示了,如果是多个数据,就要配合JSTL
标签进行遍历

需要的jsp文件attr.jsp

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试数据传递</title>
</head>
<body>

    <h1>用来测试数据的传递</h1>
    <h3>获取request作用域数据:${requestScope.username}</h3>        <!--精确搜索-->
    <h3>获取request作用域数据:${username}</h3>                     <!--作用域从小到大去搜-->
</body>
</html>

在这里插入图片描述

3.1 使用forward跳转页面的数据传递

  • 使用forward跳转页面的数据传递
  1. 单个数据
/**
 * 用来测试springmvc中数据传递机制
 */
@Controller
@RequestMapping("attr")
public class AttrController {

    /**
     * 使用forward跳转页面的数据传递
     *  1. 传递零散类型数据 2. 传递对象类型数据 3. 传递集合类型数据
     */
    @RequestMapping("test")
    public String test(HttpServletRequest request, HttpServletResponse response){
        // 1. 收集参数
        // 2. 调用业务方法 String name = "小陈";
        String name = "小陈";
        request.setAttribute("username", name);  // 存储数据
        // 3. 流程跳转
        return "attr";
    }

}

在这里插入图片描述

在这里插入图片描述

  1. 对象类型的数据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

补充:如果想要格式化日期,我们可以按照下面的步骤做

pom.xml文件中引入jstl依赖

<!--jstl-->
<dependency>
  <groupId>jstl</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>

修改原来attr.jsp文件中日期那一行:

<h3>bir: <fmt:formatDate value="${requestScope.user.bir}" pattern="yyyy-MM-dd"/></h3>

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. 集合类型的数据

在这里插入图片描述

因为在jsp页面中遍历时需要用到c标签,所以我们在jsp文件最上面加入这句话

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

在这里插入图片描述

在这里插入图片描述

补充

在这里插入图片描述

3.2 使用redirect跳转页面的数据传递

  1. 地址栏?拼接数据

只有一个数据时用?拼接(或少量数据)

传英文:

public class AttrController {

    /**
     * 使用redirect跳转传递数据
     *  // 传递数据两种方式 一种:地址栏?拼接数据(仅限于数据比较少) 二种:session对象   (传递集合和forward一样,不再赘述)
     */
    @RequestMapping("test1")
    public String test1() throws UnsupportedEncodingException {
        // 1. 收集数据
        // 2. 调用业务
        String name = "xiaochen";
        // 3. 流程跳转
        return "redirect:/attr.jsp?name="+name;
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

传中文:

在这里插入图片描述

在这里插入图片描述

  1. 使用session传递数据

当传递多个数据时用session

/**
 * 用来测试springmvc中数据传递机制
 */
@Controller
@RequestMapping("attr")
public class AttrController {

    /**
     * 使用redirect跳转传递数据
     *  // 传递数据两种方式 一种:地址栏?拼接数据(仅限于数据比较少) 二种:session对象   (传递集合和forward一样,不再赘述)
     */
    @RequestMapping("test1")
    public String test1(HttpServletRequest request) throws UnsupportedEncodingException {
        // 1. 收集数据
        // 2. 调用业务
        String name = "xiaochen";
        User user = new User("21", "百知教育", 23, new Date());
        request.getSession().setAttribute("user", user);
        // 3. 流程跳转
        return "redirect:/attr.jsp?name="+name;
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值