JAVAEE框架技术之5-springMVC参数绑定和异步交互

简介: JAVAEE框架技术之5-springMVC参数绑定和异步交互

数据绑定

springmvc作为web层技术,要接受页面传递过来的参数值,以下几种方式都是获取参数值

绑定servlet内置对象

@RequestMapping("show1")
@ResponseStatus(HttpStatus.OK) //返回void  没有页面返回,给出响应状态为200
public void test1(HttpServletRequest request , HttpServletResponse response , HttpSession session){
        //有了这些对象,之前怎么用,这里怎么用
      System.out.println(request);
        System.out.println(response);
        System.out.println(session);
    }

@PathVariable

@RequestMapping(“show2/{id}/{name}”)

@PathVariable(“id”) 指定获取请求路径中的参数值

@RequestMapping("show2/{id}/{name}")//@PathVariable("xx")参数可以省略,建议指定获取
    public String test2(@PathVariable int id ,@PathVariable String name){
        System.out.println("id:"+id);
        System.out.println("name:"+name);
        //返回String
        return "hello";//可以直接跳到视图解析器下找hello.jsp
    }

@RequestParam

属性名 属性值
value 参数名
required true(默认) false
defaultValue 默认值,如果不给参数值,就走默认值
  • 普通serlvet获取参数值
//通过绑定servlet对象,获取请求参数
    @RequestMapping("show3")
    @ResponseStatus(HttpStatus.OK)
    public void test3(HttpServletRequest request){
        System.out.println(request.getParameter("id"));
        System.out.println(request.getParameter("name"));
    }
  • @RequestParam获取参数值
/**
     * 获取请求携带的参数  show4.do?id=33&name=jack
     *  1、@RequestParam 获取请求指定参数
     *  2、value  参数据
     *  3、required 参数是否必须,默认true
     *      true: 必须
     *      false:可以不写
     *  4、 defaultValue 如果没有传值,默认给出一个值 defaultValue = "jack"
     */
    @RequestMapping("show4")
    @ResponseStatus(HttpStatus.OK)
    public void test4(
            @RequestParam(value = "id",required = true) int id,
            @RequestParam(value = "name",required = false, defaultValue = "jack") String name ){
        System.out.println("id:"+id);
        System.out.println("name:"+name);
    }

@CookieValue

/**
     * 通过后台跳转到cookie视图
     * @return
     */
    @RequestMapping("toCookie")
    public ModelAndView toCookie(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("cookie");
        return mv;
    }
    /**
     * 获取cookie的值
     * @param name
     */
    @RequestMapping("show5")
    @ResponseStatus(HttpStatus.OK)
    public void test5(@CookieValue(value = "name",required = false) String name){
        System.out.println("cookie的值为:"+name);
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <a href="/hello/show5.do">测试cookie</a>
    <script>
        document.cookie = "name=jack";
    </script>
</body>
</html>

POJO对象绑定参数

<dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.16.18</version>
    </dependency>
@Data
public class User {
    private Integer id;
    private String name;
    private Integer age;
}
/**
     * 接收绑定的pojo对象
     * @param user
     * @return
     */
    @RequestMapping("show6")
    public ModelAndView test6(User user){
        System.out.println(user);
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg",user);
        mv.setViewName("hello");
        return mv;
    }

基本数据类型绑定

/**
     * 通过后台跳转到user视图
     * @return
     */
    @RequestMapping("toUser")
    public ModelAndView toUser(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("user");
        return mv;
    }
<form action="http://localhost:8080/springmvc-test02/hello2/show18.do" method="post">
    <div>姓名:</div>
    <div><input name="name" value="张三"/></div>
    <div class="clear"></div>
    <div>年龄:</div>
    <div><input name="age" value="20"/></div>
    <div class="clear"></div>
    <div>收入:</div>
    <div><input name="income" value="100000"/></div>
    <div class="clear"></div>
    <div>结婚:</div>
    <div>
        <input type="radio" name="isMarried" value="true" checked="checked"/>是
        <input type="radio" name="isMarried" value="false"/>否</div>
    <div class="clear"></div>
    <div>兴趣:</div>
    <div>
        <input type="checkbox" name="interests" value="听歌" checked="checked"/>听歌
        <input type="checkbox" name="interests" value="书法" checked="checked"/>书法
        <input type="checkbox" name="interests" value="看电影" checked="checked"/>看电影
    </div>
    <div class="clear"></div>
    <div><input type="submit" value="提交表单"/></div>
</form>
/**
     * 接收基本数据类型
     */
    @PostMapping("show8")
    @ResponseStatus(HttpStatus.OK)
    public void test7(
            @RequestParam("name") String name,
            @RequestParam("age") Integer age,
            @RequestParam("income") Double income,
            @RequestParam("isMarried") Boolean isMarried,
            @RequestParam("interests") String[] interests){
        System.out.println("name: "+name);
        System.out.println("age: "+age);
        System.out.println("income: "+income);
        System.out.println("isMarried: "+isMarried);
        for(String str : interests){
            System.out.println("interests: "+str);
        }
    }

解决乱码问题

springmvc提供了编码过滤器

只解post中文乱码问题,注意解析源码

配置位置 web.xml

<!--编码过滤器-->
<filter>
  <!--注意这里是filter,不要配置成servlet-->
  <filter-name>encodingFilter</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>encodingFilter</filter-name><!--过滤器名称-->
  <url-pattern>/*</url-pattern><!--URL映射,给所有页面处理乱码-->
</filter-mapping>

通用页面跳转

我们发现上面我们写了很多次页面跳转的方法,其实我们可以抽取统一

@RequestMapping("to")
@Controller
public class Topage {
    /**
     * 通用页面跳转---视图解析器
       http://localhost:8080/rest/to/hello
     */  
    @RequestMapping("{page}")
    public String toPage1(@PathVariable("page") String page){
        return page;
    }
    /**
     * 通用页面跳转---webapp下视图--写着玩
     */
    @RequestMapping("wp/{page}")
    public String toPage2(@PathVariable("page") String page){
        return "forward:/"+page+".html";
    }
}
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

数组类型

<form action="/hello/show9.do" method="post">
        <input type="checkbox" name="addr" value="郑州"> 郑州   <br>
        <input type="checkbox" name="addr" value="上海"> 上海   <br>
        <input type="checkbox" name="addr" value="杭州"> 杭州   <br>
        <input type="checkbox" name="addr" value="北京"> 北京   <br>
        <input type="checkbox" name="addr" value="曹县"> 曹县 <br>
        <input type="submit" value="数组类型">
    </form>
/**
     * 接收数组
     * @param addr
     */
    @PostMapping("show9")
    @ResponseStatus(HttpStatus.OK)
    public void show9(String[] addr){
        for (String str :  addr){
            System.out.println(str);
        }
    }

绑定复杂类型

如果提交的是一个集合的数据,SpringMVC的方法形参是无法接收的,我们必须通过实体类进行包装才行

@Data
public class UserVO {
    private String name;
    private Integer age;
    private User user;
    private List<User> list;
    private Map<String,User> map;
    private String[] addr;
}
<form action="/hello/show10.do" method="post">
    姓名: <input type="text" name="name">
    年龄: <input type="text" name="age">  <br/>
    user属性中的姓名:<input type="text" name="user.name"><br/>
    user属性中的年龄:<input type="text" name="user.age">     <br/>
    list中第一个user对象的年龄:<input type="text" name="list[0].age">  <br/>
    list中第一个user对象的姓名:<input type="text" name="list[0].name"> <br/>
    list中第二个user对象的年龄: <input type="text" name="list[1].age"> <br/>
    list中第二个user对象的姓名: <input type="text" name="list[1].name"> <br/>
    map中第一个键值对中值user对象的年龄: <input type="text" name="map['one'].age">  <br/>
    map中第一个键值对中值user对象的姓名: <input type="text" name="map['one'].name"> <br/>
    map中第二个键值对中值user对象的年龄: <input type="text" name="map['two'].age"> <br/>
    map中第二个键值对中值user对象的姓名: <input type="text" name="map['two'].name"><br/>
    请选择喜欢的城市:
    <input type="checkbox" name="addr" value="郑州"> 郑州   <br>
    <input type="checkbox" name="addr" value="上海"> 上海   <br>
    <input type="checkbox" name="addr" value="杭州"> 杭州   <br>
    <input type="checkbox" name="addr" value="北京"> 北京   <br>
    <input type="checkbox" name="addr" value="曹县"> 曹县 <br>
    <input type="submit" value="复杂类型">
</form>
/**
     * 接受复杂类型
     * @param userVO
     */
    @PostMapping("show10")
    @ResponseStatus(HttpStatus.OK)
    public void show10(UserVO userVO){
        System.out.println(userVO);
    }

日期类型

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;

jsp和jstl视图解析器

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
/**
 * 把数据转发到jsp页面中进行显示
 */
@GetMapping("show20")
public ModelAndView test20(){
    ModelAndView mv = new ModelAndView();
    Person person = new Person();
    person.setId(11);
    person.setName("戈尔丹");
    person.setAge(22);
    Person person2 = new Person();
    person2.setId(11);
    person2.setName("赵日天");
    person2.setAge(33);
    Person person3 = new Person();
    person3.setId(11);
    person3.setName("叶良晨");
    person3.setAge(44);
    List<Person> list = new ArrayList<>();
    list.add(person);
    list.add(person2);
    list.add(person3);
    mv.addObject("list",list);
    mv.setViewName("list");
    return mv;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <table border="1px" cellpadding="8px" cellspacing="0px" width="80%">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Age</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${list}" var="person">
                <tr>
                    <td>${person.id}</td>
                    <td>${person.name}</td>
                    <td>${person.age}</td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
</body>
</html>

SpringMVC异步交互

在之前我们讲的请求响应都是同步的,但是在实际开发中我们都是使用异步请求,所以下面我们使用ajax发送异步请求!

在异步请求中数据传输的格式我们都是使用josn来进行传输,速度快,小巧,使用方便!!

在响应的同时,我们也是响应json字符串,在前端解析json字符串即可!

  • 回顾ajax
  • 发送ajax请求:.ajax()/.ajax() / .get() / $.post()
  • 响应json数据:new ObjectMapper().writeValueAsString()

我们学习完SpringMVC之后,就不用像之前那么麻烦了,还要创建ObjectMapper对象来转换成josn数据进行响应。

SpringMVC已经帮我们做这些事情了。SpringMVC提供了两个注解@RequestBody和@ResponseBody实现josn数据的转换

@ResponseBody

用于将controller方法返回的对象通过转换器转换为指定的格式(通常为json)之后,写入到response对象的响应体中。

添加依赖

<!-- Jackson Json处理工具包 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
</dependency>

引入jq文件

<script src="js/jquery-3.4.1.js"></script>

编写ajax代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-3.4.1.js"></script>
</head>
<body>
    <table border="1">
        <tr>
            <td>name</td>
            <td>age</td>
        </tr>
    </table>
    <script>
        $.ajax({
            url: 'UserController/ajaxResponse.do',
            type: 'POST',
            dataType:"json",
            success: function (data) {
                var str = '';
                $(data).each(function (i) {
                    str += `
                        <tr>
                            <td>${data.name}</td>
                            <td>${data.age}</td>
                            <td></td>
                        </tr>
                    `;
                });
                $("table").append(str);
            }
        });
    </script>
</body>
</html>

编写Controller

@Controller
@RequestMapping("UserController")
public class UserController {
    /**
     * 响应json串   
     * @return
     */
    @PostMapping("ajaxResponse")
    @ResponseBody //返回的对象以json的形式响应  {"name":"jack","age":99}
    public User getUser(){
        User user = new User();
        user.setName("jack");
        user.setAge(99);
        return user;
    }
}

@RestController用法

@RequestMapping("UserController")
@RestController   //@RestController  == @Controller 和 @ResponseBody
public class UserController {
    /**
     * 响应json串
     * @return
     */
    @PostMapping("ajaxResponse")
    public User getUser(){
        User user = new User();
        user.setName("jack");
        user.setAge(99);
        return user;
    }
}

@RequestBody

用于接收前端请求体中的json数据,使用@RequestBody注解就可以自动的封装指定的对象中

引入jq文件

<script src="js/jquery-3.4.1.js"></script>

编写ajax代码

  • 使用: $.ajax() 函数
  • 规则:
  • ajax提交的数据必须是一个标准的json字符串
  • ajax提交的方式必须为post,数据必须在请求体中
  • ajax提交的MIME类型必须为:application/json;charset=utf-8
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-3.4.1.js"></script>
</head>
<body>
    <script>
        $(function () {
            $.ajax({
                url: '/UserController/ajaxRequest.do',
                type: 'POST',
                data: '{"name":"jack","age":99}',
                contentType:'application/json;charset=utf-8',
                success: function (data) {
                }
            });
        });
    </script>
</body>
</html>

编写Controller

/**
     * 接受json串
     * @param user
     */
    @PostMapping("ajaxRequest")
    public void test(@RequestBody User user){
        //User(name=jack, age=99)
        System.out.println(user);
    }

小结

@RequestBody:将请求体中的json字符串,转为指定类型的java对象

@ResponseBody:将java对象转为json字符串,再设置到响应体中,返回到浏览器(客户端)

处理静态资源

测试前端代码

当点击按钮时,发现没有任何反应,这是因为SpringMVC在默认情况下,所有的静态资源都会被拦截(js,css。html,图片、视频、音频),在web.xml文件中,我们配置的拦截路径是/ 这种形式除了jsp都会被拦截

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--拦截webapp下所有静态资源,除了jsp-->
    <url-pattern>/</url-pattern>
</servlet-mapping>

把拦截路径设置为 / 时,会发现连html静态页面都无法访问

三种方式解决

对于静态资源,需要手动配置静态资源过滤。有三种形式可以选择:

  • web.xml配置 方式一
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--拦截webapp下所有资源,除了jsp-->
    <url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 处理静态资源拦截-->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>
  • springmvc-servlet.xml 配置文件
<!--
    静态资源手动映射
        mapping="/img/**" 浏览器发送请求
        location="/img/" 静态资源的路径
-->
<mvc:resources mapping="/html/**" location="/html/"/>
<mvc:resources mapping="/img/**" location="/img/" />
<mvc:resources mapping="/js/**" location="/js/" />  
<mvc:resources mapping="/css/**" location="/css/"/>
  • springmvc-servlet.xml 配置文件【简化方式】
<!-- 处理静态资源拦截-->
<!--配置tomcat默认的静态资源处理-->
<mvc:default-servlet-handler/>


目录
相关文章
|
4月前
|
前端开发 Java Apache
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
72 0
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
|
2月前
|
前端开发 JavaScript Java
MVC框架:SpringMVC(三)
MVC框架:SpringMVC
30 0
|
2月前
|
JSON 前端开发 JavaScript
MVC框架:SpringMVC(二)
MVC框架:SpringMVC
37 0
|
2月前
|
前端开发 Java 应用服务中间件
MVC框架:SpringMVC(一)
MVC框架:SpringMVC
61 0
|
2月前
|
前端开发 Java 数据库连接
探索Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty
探索Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty
|
3月前
|
JSON 前端开发 Java
【JavaEE进阶】 关于Spring mvc 响应
【JavaEE进阶】 关于Spring mvc 响应
|
3月前
|
前端开发 Java 数据库连接
认识Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty
Spring框架 Spring是一个轻量级的开源框架,用于构建企业级应用。它提供了广泛的功能,包括依赖注入、面向切面编程、事务管理、消息传递等。Spring的核心思想是控制反转(IoC)和面向切面编程(AOP)。
81 3
|
5月前
|
设计模式 前端开发 JavaScript
Spring MVC(一)【什么是Spring MVC】
Spring MVC(一)【什么是Spring MVC】
|
2月前
|
Java Apache vr&ar
springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
16 0
|
7月前
|
前端开发 Java Go
Spring MVC 和 Spring Boot 的区别
Spring MVC 和 Spring Boot 的区别
112 0