SpringMVC入门与数据绑定

2022-11-22 08:28:23 浏览数 (1)

SpringMVC与数据绑定

  • 一.Spring MVC初体验
    • 1.Spring MVC 介绍
    • 2.Spring MVC简介
    • 3.Spring 5.X 的版本变化
    • 4.Spring MVC环境配置
      • IDEA环境下创建Maven WebApp
      • Spring MVC的环境配置
  • 二.Spring MVC数据绑定
    • 1.URL Mapping(URL映射)
    • 2.Controller方法参数接收请求参数
    • 3.接收表单复合数据
    • 4.关联对象赋值
    • 5.日期类型转换
  • 三.解决中文乱码问题
  • 四.响应输出
    • 1.@ResponseBody
    • 2.ModelAndView对象的用法
  • 五.Spring MVC整合FreeMarker

一.Spring MVC初体验

从本节开始,我要学习在Spring生态体系中我们必须掌握的Web应用框架 Spring MVC。

1.Spring MVC 介绍

MVC在之前学习J2EE的时候已经了解过了。所谓MVC,是一种著名的架构模式(注意:不是设计模式)。

MVC的缩写是 Model-View-Controller首写字母的缩写。View视图是界面的部分,用于和用户进行交互,比如通过界面显示查询结果,提供表单接收用户的输入信息等。而后面的Model模型呢通常指的是我们的数据,放在java代码中,就是业务逻辑的部分。在MVC的设计理念中,如果视图中的比如某个表格中的数据来自于后端的model中,那并不是由视图主动地来通过java调用model中的某一个方法获取某一个数据,而是要通过控制器Controller,控制器Controller相当于是一个中介。控制器是整个MVC中最重要的部分,他的用途就是接收视图中所传过入的数据,然后再根据数据调用后端的业务逻辑得到结果,最后再通过控制器将后端的结果返回到视图中。也就是指视图和模型之间没有必然的连接关系。一切都是通过控制器来进行调用和返回的。其实,之前讲的Servlet就是用于开发控制器的技术,但是Servlet中提供的这些方法,使用起来有时候并不是这么方便。正是因为servlet在开发过程中有很多不方便的地方,所以spring这个机构就开发了Spring MVC,提供了简单的方式,帮我们快速的完成了web应用地开法。也就是说,作为spring mvc这个框架来说,他的主要用途就是帮我们简化web应用程序的开发。

2.Spring MVC简介

Spring MVC是Spring体系的轻量级Web MVC框架,他的主要作用就是用于替代传统的J2EE Servlet ,来让我们开发应用程序的时侯,更加的简单。

Spring MVC的核心Controller控制器,用于处理请求,产生响应。 在MVC中,界面是不允许直接访问后端的Model业务逻辑的,而是通过Controller作为一个中间者来进行传递调用,这样做的最大好处就是让我们的界面与后端java业务逻辑有效的解耦,提高了程序的可维护新。

Spring MVC基于Spring IoC容器运行,所有对象被IoC管理。

Spring MVC 文档:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html

3.Spring 5.X 的版本变化

下面来说一说版本的变化,随着时代的发展,现在Spring已经是5.X的版本了。

Spring 5.X最低要求JDK8与J2EE 7 (即Servlet 3.1 / Tomcat 8.5 )

Spring 5.X 支持JDK8/9,可以使用新特性

Spring 5.X最重要的新特性是支持响应式编程 所谓响应式编程是基于事件来的,打个比方,如果你做过界面就知道,当点击一个按钮的时候,就会触发一个单机的响应事件。那么,如果放在我们后台的编程中,也有类似的理念,当触发了某一个事件的时候,自动的去执行某一段代码。这就是响应式编程。响应式编程是另外一种编程的风格,专注于构建对事件做出响应的应用程序。

4.Spring MVC环境配置

IDEA环境下创建Maven WebApp

创建一个空的Maven项目,项目名字为first-springtime,然后进行如下配置: 先添加Web模块(点加号前要先选中模块):

下面在右侧对web进行配置: 1.首先要把web目录存储的地址改为main目录下,后面修改为srcmainwebappWEB-INFweb.xml ,然后修改web项目的版本为4.0 注意:这里的版本一定要与JDK版本和tomcat版本相对应,不然运行会报错。 版本参考下图:

2.还要设置存储页面的目录放在srcmainwebapp ,然后给应用设置一个应用上下文默认 / 即可。

创建Artifact

下面配置我就不多说了。

上面只是对web项目做配置,下面才是对Spring MVC的环境配置

Spring MVC的环境配置

1.maven中导入spring-webmvc 这个依赖。

打开pom.xml,添加如下的依赖:

代码语言:javascript复制
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.3.13</version>
</dependency>

添加这个依赖后,会发现spring的一些底层包也会一同被加入。

2.web.xml中配置DispatcherServlet

DispatcherServlet是Spring MVC中最核心的对象,DispatcherServlet用于拦截Http请求,并根据请求的URL调用与之对应的Controller方法,来完成Http请求。 web.xml:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加载applicationContext.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <!--在web应用启动时,自动创建Spring IoC容器,并初始化DispatcherServlet-->
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--"/"代表要拦截所有的请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--将请求的字符集转换为UTF-8-->
    <filter>
        <filter-name>characterFilter</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>characterFilter</filter-name>
        <!--对所有的请求进行过滤-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

在resources目录下创建applicationContext.xml文件,下面是applicationContext.xml的初始配置: applicationContext.xml

代码语言:javascript复制
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

</beans>

3.在applicationContext.xml中,配置applicationContext的mvc标记

配置context:component-scan这个标签的作用: 在Spring IoC初始化过程中,自动创建并管理指定包及其子包中拥有@Repository 、@Service 、@Controller 、 @Component 这些注解的对象。

代码语言:javascript复制
<!--自动扫描组件,自动扫描符合条件的bean-->
    <context:component-scan base-package="com.haiexijun.springmvc"></context:component-scan>
    <!--启用Spring MVC的注解开发模式-->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=utf-8</value>
                        <value>application/json;charset=utf-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
    <mvc:default-servlet-handler/>

4.开发Controller控制器 到这里,Spring MVC就基本上配置得差不多了,下面来开发一个Controller来体验一下。

在java下com.haiexijun.springmvc下面创建一个controller包,然后创建一个java类TestController。在类名上面添加**@Controller注解**。里面定义了一个test方法,这个方法返回一个SUCCESS字符串。那如何让这个方法处理请求呢?我们只需要在这个方法上添加上两个注解就可以了。@GetMapping() 注解用于将当前的方法绑定某个get类型请求的URL,比如@GetMapping("/t")则为绑定localhost/t这个URL,地址栏中输入localhost/t就能访问到这个方法了。@ResponseBody 注解作用是直接向响应输出字符串数据,不跳转页面。

代码语言:javascript复制
package com.haiexijun.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {
    @GetMapping("/t") //用于将当前的方法绑定某个get类型请求的URL,比如localhost/t
    @ResponseBody  //作用:直接向响应输出字符串数据,不跳转页面
    public String test(){
        return "SUCCESS";
    }

}

下面还要进行一项配置,把maven的依赖导出项目时加入到lib目录下: 全选中后,右键put进去。

运行启动。输入localhost:8888/t,成功打印SUCCESS

二.Spring MVC数据绑定

1.URL Mapping(URL映射)

URL Mapping 指将URL与Controller方法绑定,通过将URL与方法绑定,Spring MVC便可以通过Tomcat对外暴露服务。

我们可以这么理解,作为web应用来说,所有对外暴露的接口都是一个个URL网址,我们通过URL来执行后端的程序代码。

URL Mapping注解 @RequestMapping 通过绑定 @GetMapping 绑定Get请求 @PostMapping 绑定Post请求

下面来对这三种注解进行演示: 创建一个新的控制器类,先编写如下代码测试:

代码语言:javascript复制
package com.haiexijun.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class URLMappingController {

    @GetMapping("/g")
    @ResponseBody
    public String getMapping(){
        return "this is get method";
    }

    @PostMapping("/p")
    @ResponseBody
    public String postMapping(){
        return "this is post method";
    }

}

运行项目后打开浏览器,分别输入对应的url地址,get请求成功被响应,post请求因为不能通过浏览器来访问,所以报405错误。

我们可以通过编写一个表单来验证post请求。这里不演示了。

**@RequestMapping可写在类名前。这个注解在大多数情况下是用于进行URL的全局设置的,我们都知道作为URL,它可能是有多级结构的。**比如,希望当前这个Controller里面所有的映射地址都是以 /um开始的。如果不用@RequestMapping,那GetMapping和PostMapping都要改为“/um/g”和“/um/p” .

代码语言:javascript复制
package com.haiexijun.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/um")
public class URLMappingController {

    @GetMapping("/g")
    @ResponseBody
    public String getMapping(){
        return "this is get method";
    }

    @PostMapping("/p")
    @ResponseBody
    public String postMapping(){
        return "this is post method";
    }
}

@RequestMapping也可以写在方法名前,表示该方法不在区分post请求和get请求了。也就是说所有类型的请求都可以访问得到这个方法所映射的URL了。但并不推荐这么来用 @RequestMapping也可以配置,使其分post请求和get请求。配置value和method就好了。

代码语言:javascript复制
    @RequestMapping(value = "/g",method = RequestMethod.GET)
    @ResponseBody
    public String getMapping(){
        return "this is get method";
    }

2.Controller方法参数接收请求参数

在大多数情况下,一个请求发过来的时候是要包含一些数据,这些数据通常是由请求参数的方式来体现的。比如说用户登陆的时候,要输入用户名和密码,那么这些数据就以post请求参数的形式发送到Controller的方法中。

接收请求参数的常用做法: 可以通过Controller方法接收参数,或使用java Bean接收数据。

下面是通过Controller方法参数接收请求参数,方法会自动进行类型转换。

对于get请求,有一个小小的注意点。就是如果get请求输入的请求参数为manager_name(localhost:8888/g?manager_name=lily)的话,controller方法里面的参数该怎么写呢?java可不支持manager_name的命名规则。这时候就要用到一个新的注解:@RequestParam 这个注解写在参数前,专用于这种特殊的参数进行描述的,@RequestParam还要传入原始的请求参数。

代码语言:javascript复制
    @RequestMapping(value = "/g",method = RequestMethod.GET)
    @ResponseBody
    public String getMapping(@RequestParam("manager_name") String managerName){
        return "this is get method";
    }

这里其实如果注解里面添加了原始的参数名称,后面的请求参数则可以为任意,比如abc都可以。

## 3.Controller实体对象接收请求参数(使用javaBean接收请求参数) 假设一个表单的输入项非常的多没有一百多个的话,问题就产生了,难道我要将这一百多个输入项的参数一个个在controller方法里面写出来吗?可想而至,方法声明该会有多长啊?维护起来是十分困难的。为了解决这个问题,Spring MVC允许我们一次性将我们前台输入的数据保存为指定的javaBean。一步到位,完成了由数据到对象的转换工作。

下面来演示具体使用步骤: 创建一个entity包,在包下面创建一个User实体类。这个实体类就是一个标准的javaBean。

代码语言:javascript复制
package com.haiexijun.springmvc.entity;

public class User {
    private String username;
    private Long password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Long getPassword() {
        return password;
    }

    public void setPassword(Long password) {
        this.password = password;
    }
}

编写一个表单:

代码语言:javascript复制
<form action="/um/p1" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="提交">
</form>

然后在Controller里面编写一个方法: 在程序运行的时候Spring MVC就会自动创建User 这个对象,并且根据前面的请求参数,便会在实体内寻找同名属性,对User实体内的属性依依赋值。要保证前台传入的参数名与属性名保持一致,并且对于数值类型,也得要求前台传入的这个数据能够成功地转换到实体属性对应的类型。

代码语言:javascript复制
    @PostMapping("/p1")
    @ResponseBody
    public String postMapping1(User user){
        return user.getUsername() ":" user.getPassword();
    }

启动运行:

3.接收表单复合数据

下面通过一个案例来演示复合数据获取。比如复选框传过来的数据。

知识点:首先我们会利用数组或者List接收请求中的复合数据。利用@RequestParam为参数设置默认值。使用Map对象接收请求参数及注意事项。

下面通过代码学习: 下面是前端html表单的代码:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学员调查问卷</title>
    <style>
        .container {
            position: absolute;
            border: 1px solid #cccccc;
            left: 50%;
            top: 50%;
            width: 400px;
            height: 300px;
            margin-left: -200px;
            margin-top: -150px;
            box-sizing: border-box;
            padding: 10px;
        }
        h2{
            margin: 10px 0px;
            text-align: center;
        }
        h3{
            margin: 10px  0px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h2>学员调查问卷</h2>
        <form action="./apply" method="post">
        <h3>您的姓名</h3>
        <input name="name" class="text"  style="width: 150px">
        <h3>您正在学习的技术方向</h3>
        <select name="course" style="width: 150px">
            <option value="java">Java</option>
            <option value="h5">HTML5</option>
            <option value="python">Python</option>
            <option value="php">PHP</option>
        </select>
        <div>
            <h3>您的学习目的:</h3>
            <input type="checkbox" name="purpose" value="1">就业找工作
            <input type="checkbox" name="purpose" value="2">工作要求
            <input type="checkbox" name="purpose" value="3">兴趣爱好
            <input type="checkbox" name="purpose" value="4">其他
        </div>
        <div style="text-align: center;padding-top:10px" >
            <input type="submit" value="提交" style="width:100px">
        </div>
        </form>

    </div>
</body>
</html>

在Controller包下创建FormController类,下面编写代码,进行表单处理:

代码语言:javascript复制
package com.haiexijun.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class FormController {

    //通过数组来接收表单复合数据
    @PostMapping("/apply")
    @ResponseBody
    public String apply(String name,String course,Integer[] purpose){
        return name " " course " " purpose.length;
        
    }
}

启动运行:

这里再扩展一个小的知识点,如果作为我们上面的表单,假如name我们没有填写任何东西。那么接收时,controller里面的参数会为一个空的值,那对于空的值进行后续操作时,程序就很可能产生错误。为了解决这个情况,我们也可以对可能不存在的参数设置默认值。这里也用到@RequestParam注解来设置默认值。如下:

代码语言:javascript复制
    @PostMapping("/apply")
    @ResponseBody
    public String apply(@RequestParam(value = "name",defaultValue = "haiexijun") String name, String course, Integer[] purpose){
        return name " " course " " purpose.length;

    }

上面,name的默认值就被设置为haiexijun了,当表单的name项为填入参数时,就会默认值为haiexijun。

下面继续回到复合数据的接受,作为数组接收数据固然没有问题,但是大家发现了没有,数组其实用得越来越少了。因为java提供了更加有效的数据结构,就是集合。就可以通过List集合来保存数据。用法其实也差不多,默认以ArrayList来存储数据。区别在于,用List集合接收符合数据,要在前面添加@RequestParam注解 ,下面编写代码:

代码语言:javascript复制
    //通过List来接收表单复合数据
    @PostMapping("/apply")
    @ResponseBody
    public String apply(String name, String course, @RequestParam List<Integer> purpose){
        return name " " course " " purpose.size();

    }

上面对于这些参数都是单独接收的,下面来试试采取对象的形式来接收。 在entity包下面创建一个新的实体类Form

代码语言:javascript复制
package com.haiexijun.springmvc.entity;

import java.util.List;

public class Form {
    private String name;
    private String course;
    private List<Integer> purpose;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public List<Integer> getPurpose() {
        return purpose;
    }

    public void setPurpose(List<Integer> purpose) {
        this.purpose = purpose;
    }
}

对controller里面的apply方法进行修改:

代码语言:javascript复制
    //通过List来接收表单复合数据
    @PostMapping("/apply")
    @ResponseBody
    public String apply(Form form){
        return form.getName() " " form.getCourse() " " form.getPurpose().size();
    }

下面再扩展一个额外的知识点,用Map来接收表单数据。同样要加@RequestParam注解,并且表单传过来的参数不能有复合数据,不然只显示复合数据的第一项。

代码语言:javascript复制
    //通过List来接收表单复合数据
    @PostMapping("/apply")
    @ResponseBody
    public String apply(@RequestParam Map map){
        return (String) map.get("name");
    }

4.关联对象赋值

关联对象就是在一个对象中引用了另外一个对象,我们需要对这个被引用的对象进行赋值的操作。

下面用一个案例来了解一下 在我们上网的时候,一些关键性的操作往往是要进行实名认证的,比如我们去12306买票,除了输入用户名和密码以外,你还要去登记你的姓名、身份证号、以及身份证的过期时间。等等这些信息。这时,就要对IdCard对象关联赋值了。

我们要在前端表单进行一下修改,把原有的身份证相关输入的部分变成对象名.属性名的形式。

5.日期类型转换

本节学习一个非常实用的技巧,在SpringMVC中接收日期类型的数据。我们都知道全世界各地,对于日期的表达方式都不同,我们如何接收程序中的日期数据,然后将他转换为日期对象呢?

代码语言:javascript复制
<form action="/apply" method="post">
    <input type="text" name="createTime">
    <input type="submit" value="提交">
</form>

上面是前端的一个简单的表单,输入日期,然后再下面的controller里面的方法中进新处理:

代码语言:javascript复制
    @PostMapping("/apply")
    @ResponseBody
    public String apply(Date createTime){
        return createTime;
    }

但是上面这样写明显是不行的。spring mvc无法将它转换成日期类型

必须要加上@DateTimeFormat这个注解。 这个注解专用于将前台传入的日期字符串转换为日期格式。注解里面pattern要传入特定的日期格式。

代码语言:javascript复制
    @PostMapping("/apply")
    @ResponseBody
    public String apply(@DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime){
        return createTime.toString();
    }

下面运行测试一下:

如果要javaBean里面接收参数的话,就要再Bean中的Date类型的参数上面添加@DateFormat注解。

三.解决中文乱码问题

本节来学习如何在Spring MVC中解决中文乱码的问题。

Tomcat默认使用的字符集是ISO-8859-1,属于西欧字符集。解决乱码的核心思路就是将ISO-8859-1转换为UTF-8。Controller中请求与响应都要设置UTF-8字符集。

中文乱码的配置: Get请求乱码—server.xml(tomcat里面的)中添加URIEncoding属性。

Post请求乱码—web.xml(项目的)中配置CharacterEncodingFilter这个过滤器,通过spring提供的这个过滤器来解决post请求当中中文乱码的问题。

代码语言:javascript复制
<web app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
	   ···············
	   ················
    <filter>
        <filter-name>characterFilter</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>characterFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web app>

Response响应乱码—Spring配置StringHttpMessageConverter这个消息转换器来往成响应输出的中文解决。 打开applicationContext.xml文件,在<mvc:annotation-driven>里面添加如下的代码:

代码语言:javascript复制
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

    <!--自动扫描组件,自动扫描符合条件的bean-->
    <context:component-scan base-package="com.haiexijun.springmvc"></context:component-scan>
    <!--启用Spring MVC的注解开发模式-->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=utf-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
    <mvc:default-servlet-handler/>
</beans>

基本上在我们任何一个项目中,这三部都要进行设置。

四.响应输出

前面一直在学习请求中如何接收数据,如何URL映射,本节学习响应是如何对外输出结果的。

在响应中产生结果主要有两种方式,第一种是在我们Controller的方法上增加@ResponseBody注解,来产生响应文本。我们光产生文本很多时候是不够的,往往是需要显示对应的页面。就要用到ModelAndView对象,在利用模板引擎渲染输出。

1.@ResponseBody

@ResponseBody直接产生响应体的数据,过程不涉及任何视图,@ResponseBody可产生标准字符串/JSON/XML等格式数据。@ResponseBody被StringHttpMessageConverter所影响。

2.ModelAndView对象的用法

在我们项目开发的时候,很多时候都是需要进行页面展现的,那如果要在SpringMVC中进行页面展现的话,就要实用ModelAndView这个对象了。所谓ModelAndView对象是指“模型(数据)与视图(界面)”对象,这个对象的作用呢就是将模型和视图进行绑定。通过ModelAndView对象可以将包含数据对象与模板引擎进行绑定。Spring MVC中默认的View是JSP,也可以配置其他模板引擎。

下面来小小的演示一下:

代码语言:javascript复制
    //返回值类型为ModelAndView
    @GetMapping("/view")
    public ModelAndView showView(){
        //构造函数里面传入一个jsp页面
        ModelAndView mav=new ModelAndView("view.jsp");
        return mav;
    }

然后创建view.jsp页面。

代码语言:javascript复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>I am view page</h1>
</body>
</html>

浏览器输入URL地址后:

上面的案例你可能会觉得也没什么了不起嘛,其实可以将方法中传入的参数进行在里面渲染后输出的。 下面对进行更改讲解:

代码语言:javascript复制
    @GetMapping("/view")
    public ModelAndView showView(Integer userId){
        //构造函数里面传入一个jsp页面
        ModelAndView mav=new ModelAndView("view.jsp");
        User user=new User();
        if (userId==1){
            user.setUsername("lily");
        }else if (userId==2){
            user.setUsername("smith");
        }
        mav.addObject("u",user);
        return mav;
    }

上面接收一个get请求的参数,然后把参数传进JSP内渲染。

代码语言:javascript复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>I am view page</h1>
<hr/>
<h2>uaername:${u.username}</h2>
</body>
</html>

但是这些还是远远不够的,下面就来对ModelAndView进行深入的学习。

作为数据绑定,ModelAndView对象提供了一个addObject()方法,addObject()方法设置的属性默认存放在当前请求中。里面存入的对象可以是任何java对象。ModelAndView对象默认使用请求转发(forward)至页面。 如果要使用响应重定向,就要使用 new ModelAndView(“redirect:/xxx.jsp”) ,即添加redirect

ModelAndView可以不在创建对象时,在构造方法里面写跳转的地址,可以在创建对象后,通过ModelAndView对象的setViewName()方法来设置跳转的视图的地址。

代码语言:javascript复制
 ModelAndView mav=new ModelAndView();
 mav.setViewName("/view.jsp")

下面再来扩展一个知识点,就是利用String与ModelMap这两个对象来实现与 ModelAndView类似的一个功能。 Controller方法返回String的情况: 1.方法被@ResponseBody注解,SpringMVC注解响应String字符串本身。 2.方法不存在@ResponseBody注解,SpringMVC处理String为视图(页面)

代码语言:javascript复制
    @GetMapping("/view")
    public String showView(Integer userId, ModelMap modelMap){
        String view="/view.jsp";
        User user=new User();
        if (userId==1){
            user.setUsername("lily");
        }else if (userId==2){
            user.setUsername("smith");
        }
        //与ModelAndView的addObject完全相同
        modelMap.addAttribute("u",user);
        return view;
    }

五.Spring MVC整合FreeMarker

整合的步骤主要分为3步: 1.pox.xml中引入freemarker的maven依赖和一个Spring上下文的支持包。 Spring上下文的支持包要与spring-webmvc版本一致。

代码语言:javascript复制
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.13</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.3.13</version>
        </dependency>
    </dependencies>

2.启用Freemarker模板引擎 在applicationContext.xml中添加如下配置:

代码语言:javascript复制
    <bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <!--设置响应输出,解决中文乱码-->
        <property name="contentType" value="text/html;charset=utf-8"/>
        <!--指定FreeMarker模板文件拓展名-->
        <property name="suffix" value=".ftl"/>
    </bean>

3.配置Freemarker参数 在applicationContext.xml中添加如下配置:

代码语言:javascript复制
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <!--设置模板保存的目录-->
        <property name="templateLoaderPath" value="/WEB-INF/ftl"/>
        <!--其他设置-->
        <property name="freemarkerSettings">
            <props>
                <!--设置Freemarker脚本与数据渲染时使用的字符集-->
                <prop key="defaultEncoding">UTF-8</prop>
            </props>
        </property>
    </bean>

具体使用,以后案例用到在演示。

0 人点赞