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

1. SpringMVC中map类型参数接收

在CollectionVO对象中定义一个map类型的名为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类型参数的接收

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第1张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第2张图片

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第3张图片

当我们在插入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 - _ . ~ 以及所有保留字符 ! * ’ ( ) ; : @ & = + $ , / ? # [ ]没有%

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第4张图片

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第5张图片

学习于:在请求目标中找到无效字符。有效字符在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" %>



    
    
    
    测试参数接收



    

测试对象和零散对象接收

用户id:
用户name:
用户age:
用户bir:

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第6张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第7张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第8张图片

# 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" %>



    
    
    
    测试参数接收



    

测试对象和零散对象接收

用户id:
用户name:
用户age:
用户bir:

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

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

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第9张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第10张图片

测试:

/**
 * 用来测试参数接收的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";
    }
}

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第11张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第12张图片

其实上面这个方法就已经解决了下面的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" %>



    
    
    
    测试参数接收



    

测试对象和零散对象接收

用户id:
用户name:
用户age:
用户bir:
  • 使用自定义的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() {

    }
}

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第13张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第14张图片

web.xml文件中配置filter


<filter>
  <filter-name>charsetfilter-name>
  <filter-class>com.baizhi.filter.CharacterEncodingFilterfilter-class>
  <init-param>
    <param-name>encodingparam-name>	
    <param-value>UTF-8param-value>		
  init-param>
filter>
<filter-mapping>
  <filter-name>charsetfilter-name>
  <url-pattern>/*url-pattern>
filter-mapping>

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第15张图片

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

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

  
  <filter>
    <filter-name>charsetfilter-name>
    <filter-class>org.springframework.web.filterfilter-class>
    <init-param>
      <param-name>encodingparam-name>
      <param-value>UTF-8param-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>charsetfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第16张图片

测试:

在地址栏输入:

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第17张图片

3. SpringMVC中数据传递机制

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第18张图片

# 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" %>



    
    
    
    测试数据传递



    

用来测试数据的传递

获取request作用域数据:${requestScope.username}

获取request作用域数据:${username}

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第19张图片

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";
    }

}

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第20张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第21张图片

  1. 对象类型的数据

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第22张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第23张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第24张图片

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

pom.xml文件中引入jstl依赖


<dependency>
  <groupId>jstlgroupId>
  <artifactId>jstlartifactId>
  <version>1.2version>
dependency>

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

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第25张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第26张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第27张图片

  1. 集合类型的数据

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第28张图片

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

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

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第29张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第30张图片

补充

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第31张图片

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;
    }
}

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第32张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第33张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第34张图片

传中文:

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第35张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第36张图片

  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;
    }
}

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第37张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第38张图片

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第39张图片

总结:

SpringMVC中map类型参数接收和乱码问题以及数据传递机制_第40张图片

你可能感兴趣的:(SpringMVC,tomcat,java,开发语言,后端,spring)