springmvc-跳转方式、数据处理、数据显示、乱码问题

118 阅读2分钟

我是跟着b站狂神说的SpringMVC来进行学习的。这是我的笔记。www.bilibili.com/video/BV1aE…

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

跳转方式:转发和重定向

视图解析器作用

在有视图解析器的前提下,我们一般通过 Controller 类返回的字符串作为页面名称作为指向。

在 Controller 类都会返回一个字符串。这个字符串代表着你的页面的名称

我们通过视图解析器,将页面名称拼接成一个项目内的指定页面地址

页面地址 = 【视图解析器前缀】+ 页面名称 +【视图解析器后缀】

<!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>
  • 后续可能会学习其他的视图解析器,所以不一定要记住写法,但是需要知道有这个东西和它的作用。

不配置视图解析器进行跳转

通过SpringMVC来实现转发和重定向 - 无需视图解析器;

测试前,需要将视图解析器注释掉

  • 转发方法一

    Controller 类直接返回视图资源全路径和资源后缀

    @GetMapping("/s/t1")
        public String test1() {
            // 转发写法一:web 包下对用视图的全路径
            return "WEB-INF/jsp/test.jsp";
        }
    
  • 转发方法二

    通过在路径前 添加‘forward:’

    @GetMapping("/s/t2")
    public String test2() {
        // 转发写法二:通过在路径前 添加‘forward:’
        return "forward:/WEB-INF/jsp/test.jsp";
    }
    
  • 重定向方法一

    通过在路径前 添加‘redirect:’

    @GetMapping("/s/t3")
    public String test3() {
        // 重定向方法一:通过在路径前 添加‘redirect:’
        return "redirect:/WEB-INF/jsp/test.jsp";
    }
    

配置视图解析器进行跳转

  • 转发

    有视图解析器默认转发

    @RequestMapping("/test2")
    public String test2(Model model) {
        model.addAttribute("msg", "test2");
        return "test";
    }
    
  • 重定向

    通过在路径前 添加 ‘redirect:’

    @RequestMapping("/test2")
    public String test3(Model model) {
        model.addAttribute("msg", "test3");
    
        return "redirect:/WEB-INF/jsp/test.jsp";
    }
    

数据处理

我们常常需要从前端接收数据进行操作。所以需要对前端传来的数据进行处理。

处理方法有三种

方法一:提交的域名称和处理方法的参数名一致

从图中可以看出,红色框框起来的两个参数名是一致的。

image-20220413115405996

在保证域名称和处理方法的参数名一致的情况下,我们通过一下两种方法来传参

  1. 在域名称将单个参数?paramName=value 的方式传入;
  2. 多个参数?paramName1=value1 & paramName2=value2 &......& paramName=value 的方式传入

【Controller 代码】

    @GetMapping("/test1")
    public String test1(String name, Model model) {
        // 1. 接收前端参数
        System.out.println(name);

        // 2. 将接收结果返回到前端
        model.addAttribute("msg", name);

        // 3. 视图跳转
        return "test";
    }

【测试jsp代码】

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

【域名称】

http://localhost:8080/user/test1?name=hyz

方法二:提交的域名称和处理方法的参数名不一致

从图中可以看出,域名称参数和处理方法的参数名不一致

image-20220413120540730

我们只需要在参数前加一个注解 @RequestParam("urlParamName") 就可以识别了。

image-20220413121601508

【建议无论域名称和处理方法的参数名是否一致,都建议使用方法二,添加 @ResquestParam 注解。】

【这样做方便我们分辨处理方法中哪些参数是需要接收前端参数哪些是不需要的】

【Controller 代码】

@GetMapping("/test2")
public String test2(@RequestParam("username") String name, Model model) {
    // 1. 接收前端参数
    System.out.println(name);

    // 2. 将接收结果返回到前端
    model.addAttribute("msg", name);

    // 3. 视图跳转
    return "test";
}

【域名称】

http://localhost:8080/user/test2?name=hyz
http://localhost:8080/user/test2?username=hyz

方法三:提交的是一个对象

当前端是一个表单之类的,提交的数据很多。我们可以做成一个对象来统一接收。只需要

要求提交的表单域和对象的属性名一致 , 参数使用对象即可。

image-20220413123846739

如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。

【User】

package cn.hyz.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author workplace
 * @date 2022/4/13 11:30
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private int age;
}

【Controller】

@GetMapping("/test3")
public String test3(User user,Model model) {
    System.out.println(user);
    model.addAttribute("msg", user);
    return "test";
}

【域名称】

http://localhost:8080/user/test3?id=1&name=hyz&age=21
http://localhost:8080/user/test3?userid=1&username=hyz&userage=21

数据显示到前端

方法一:通过 ModelAndView

我们通过 addObject 来接收结果返回到前端,通过 setViewName 跳转视图

public class HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = new ModelAndView();
        // 业务代码
        String str = "helloHYZ";
        mv.addObject("str", str);
        // 视图跳转
        mv.setViewName("test");

        return mv;
    }
}

乱码问题

乱码测试

测试一下,我们在表单里输入中文再跳转页面将后端接收的内容显示出来

【表单】

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="/e/t" method="post">
    <input type="text" name="name">
    <input type="submit">
</form>

</body>
</html>

【Controller】

通过两个方法进行页面跳转,

@Controller
public class EnCodingController {
    @GetMapping("/form")
    public String test1() {
        return "form";
    }
  
    @PostMapping("/e/t")
    public String test2(@RequestParam("name") String name, Model model) {
        System.out.println(name);
        model.addAttribute("msg", name);
        return "test";
    }
}

【展示页面】

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

【结果】

  • 输入中文

image-20220414125128267

  • 提交并显示

    image-20220414161128261


解决方法

我们只需要在 xml 配置文件中添加 springmvc 自带的过滤器就可以解决这种问题

<!--
配置过滤器
-->
<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 添加过滤器后的效果

    image-20220414161827251

    image-20220414161840947