springmvc的简单理解与使用

开发模式:

1、模式一(Model One):JSP(只使用JSP进行开发)

Servlet:本质是一段Java程序,适合处理业务逻辑,但是Servlet不适合输出一个html网页(因为在Servlet中输出网页,得通过response获取流,通过out.write一行一行将html标签等内容输出到浏览器中)

Html:是用于开发网页的语言,适合作为网页输出,但是html是一个静态Web资源,无法展示动态的数据

JSP:也是开发网页的语言,也可以输出一个网页(html),并且JSP中可以书写Java代码(或者JSP标签,其实底层也是Java代码)展示动态数据。
JSP的出现既解决了Servlet不适合输出网页的问题,同时也解决了HTML无法展示动态数据的问题!
在一些中小型项目中只用JSP进行开发(持续了一段时间),JSP负责的工作:
(1)获取请求中携带的数据,对请求进行处理
(2)如果在处理的过程中需要访问数据库,JSP中可以书写Java代码访问数据库
(3)请求处理的结果仍然是由JSP负责响应
JSP中要处理很多的内容,必然要写很多Java代码,这样会导致JSP内部的HTML代码和Java代码混杂在一起,造成JSP页面结构的混乱,可读性变差,后期难以维护。

2、模式二(Model Two):Servlet+JavaBean+JSP:

(1)Servlet:接收请求中的数据(请求参数)、调用某一个JavaBean对请求进行处理、调用某一个JSP展示请求处理的结果
将请求数据封装到JavaBean内部
调用JavaBean方法处理请求

(2)JavaBean:处理请求(封装数据、处理业务逻辑、访问数据库)
业务Bean: 负责处理业务逻辑
实体Bean: 负责封装数据
User类(username/password/nickname/email..)

(3)JSP:只负责展示/响应对请求处理的结果

-----------------------------------------

** MVC设计模式:

-----------------------------------------
MVC设计模式是一种通用的软件编程思想,不仅仅适用于Java语言。
在MVC设计模式中认为, 任何软件都可以分为三部分组成:
(1)控制程序流转的控制器(Controller)
(2)封装数据处理数据的模型(Model)
(3)负责展示数据的视图(view)
并且在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面这三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分。
如果某一个模块发生变化,应该尽量做到不影响其他两个模块。这样做的好处是,软件的结构会变得更加的清晰,可读性强。有利于后期的扩展和维护,并且代码可以实现复用。

初识SpringMVC

1.SpringMVC是对Servlet的封装:Servlet的缺点

1、通常情况下,一个Servlet类只负责处理一个请求,若项目中有成百上千个请求需要处理,就需要有成百上千个Servlet类,这样会使得项目中Servlet类的个数暴增;

2、在Servlet3.0版本之前,每一个Servlet都需要在web.xml文件中至少做八行配置信息,配置内容多且繁琐。当Servlet特别多时,web.xml配置量太多,不利于团队开发;

3、当通过客户端提交参数到服务器,通过Servlet进行接收时,无论数据本身是什么格式,在Servlet中一律按照字符串进行接收,后期需要进行类型转换,复杂类型还需要特殊处理,特别麻烦!

String value = request.getParameter(String name);

4、servlet具有容器依赖性,必须放在服务器中运行,不利于单元测试;

...

2.Springmvc执行原理

Springmvc是spring框架的一个模块,spring和springmvc无需中间整合层整合。Springmvc是一个基于mvc的web框架。

(1).用户发送请求 至 前端控制器(DispatcherServlet);

提示:DispatcherServlet的作用:接收请求,调用其它组件处理请求,响应结果,相当于转发器、中央处理器,是整个流程控制的中心

(2).前端控制器(DispatcherServlet)收到请求后调用处理器映射器(HandlerMapping)

处理器映射器(HandlerMapping)找到具体的Controller(可以根据xml配置、注解进行查找),并将Controller返回给DispatcherServlet;

(3).前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器经过适配调用具体的Controller;(Controller--> service --> Dao --> 数据库)

Controller执行完成后返回ModelAndView,

提示:Model(模型数据,即Controller处理的结果,Map) View(逻辑视图名,即负责展示结果的JSP页面的名字)

处理器适配器(HandlerAdapter)将controller执行的结果(ModelAndView)返回给前端控制器(DispatcherServlet);

(4).前端控制器(DispatcherServlet)将执行的结果(ModelAndView)传给视图解析器(ViewReslover)

视图解析器(ViewReslover)根据View(逻辑视图名)解析后返回具体JSP页面

(5).前端控制器(DispatcherServlet)根据Model对View进行渲染(即将模型数据填充至视图中);

前端控制器(DispatcherServlet)将填充了数据的网页响应给用户。

其中整个过程中需要开发人员编写的部分有ControllerServiceDaoView;

SpringMVC环境搭建之入门案例:hello springmvc!

需求:

(1)通过浏览器访问 http://localhost:8080/项目名称/hello 地址,在控制台输出 "hello springmvc"

(2)将请求转向(跳转到) /WEB-INF/pages/home.jsp 页面

1、通过Maven创建web工程

 2、在pom.xml中引入springmvc所需jar包:将下面的配置直接拷贝到pom.xml中的根标签内

<dependencies>
    <!-- 单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>

    <!-- SpringMVC的jar包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.1.3.RELEASE</version>
    </dependency>
    
    <!-- servlet 和 jsp的jar包 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </dependency>
    
    <!-- java对象转换json的工具类
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.5.1</version>
    </dependency>
     -->
</dependencies>

注:粘贴后一般会有格式问题,可以通过选中pom.xml文件中的所有内容:Ctrl+A,再利用快捷方式对齐:Ctrl+I (后续的情况也是一样)。

3、在web.xml中配置前端控制器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    
    <!-- 配置springmvc前端控制器(DispatcherServlet) ctrl+shift+T, 将所有请求交给springmvc来处理 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        
        <!-- 配置springmvc核心配置文件的位置(contextConfigLocation是固定的名字,不能写错!),
           默认Springmvc的配置文件是在WEB-INF目录下,默认的名字为springmvc-servlet.xml,如果要放在其他目录,则需要指定如下配置:
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-config.xml</param-value>
        </init-param>       
    </servlet>
    <!-- 配置前端控制器拦截对当前应用下的所有资源的访问(除了JSP):其中的斜杠(/)表示拦截所有请求(除JSP以外), 
       所有请求都要经过springmvc前端控制器。为什么不拦截JSP呢??? -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- 配置(启用)springmvc的乱码处理过滤器,用于解决POST提交的中文参数乱码问题! -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <!-- /* 表示拦截所有请求,对所有请求都进行过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

eclipse中的两个常用的快捷键可以大大提升查找文件的效率,分别是:

ctrl+shift+r : open resource, 打开资源.
它可以打开当前eclipse的工作区中所有(打开的)工程中所有类型的文件,但只限手动编写的文件,不含工程中引用到的jar包中的类、接口;
ctrl+shift+t : open type, 打开类型.
它可以打开当前eclipse的工作区中所有(打开的)工程中所有java文件,包括jar包中的类和接口.
二者都支持通配符搜索.

注:右键点击工程名,有一个close project选项,单击之后,项目将被关闭,项目中的资源将不会被两个快捷键访问到.
————————————————
版权声明:本文为CSDN博主「qgfjeahn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qgfjeahn/java/article/details/52526526

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4、关于SpringMVC的乱码处理:

相比于Servlet需要更改部分源代码的方式,springmvc提供了更为简单高效解决请求中文参数乱码的方案,就是在web.xml中加入如下代码(配置请求参数乱码过滤器),就可以解决POST提交的中文参数乱码问题!达到一劳永逸的效果。

    <!-- 配置(启用)springmvc的乱码处理过滤器,用于解决POST提交的中文参数乱码问题! -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <!-- /* 表示拦截所有请求,对所有请求都进行过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Servlet中,两种请求方式乱码解决方案回顾:

(1)如果请求方式为POST提交,无论哪个版本的tomcat,POST提交的中午参数在获取时,必然会出现乱码的问题,解决方式是在任何获取参数的代码之前,添加如下代码:

request.setCharacterEncoding("utf-8");

(2)如果请求方式为GET提交,tomcat8及之后的版本已经解决了GET提交的中文参数乱码问题,因此不需要处理;在 tomcat7 及之前的版本中,获取GET提交的中文参数仍有乱码,解决方法是:只需要在[tomcat]/conf/server.xml中添加如下配置也可以解决乱码问题。

5、创建并配置springmvc-config.xml

直接复制下面配置文件的内容即可!

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
                        http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    <!-- 1.配置前端控制器放行静态资源(html/css/js等,否则静态资源将无法访问) -->
    <mvc:default-servlet-handler/>
    
    <!-- 2.启动默认配置,配置注解驱动,用于识别注解(比如@Controller) -->
    <mvc:annotation-driven></mvc:annotation-driven>
    
    <!-- 3.配置需要扫描的包:spring自动去扫描 base-package 下的类,如果扫描到的类上有 @Controller、@Service、@Component等注解,
       将会自动将类注册为bean 
     -->
    <context:component-scan base-package="com.fhy.controller">
    </context:component-scan>
    
    <!-- 4.配置内部资源视图解析器
        prefix:配置路径前缀
        suffix:配置文件后缀
        URL路径:http://localhost:8080/springmvc/hello 
        根据以下配置执行testHello方法, 方法最后 return "home"; 其实就是跳转到名称为home的jsp文件 /WEB-INF/pages/home.jsp
     -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

6、springmvc前端控制器放行静态资源的解决办法

在配置SpringMVC开发环境时,会在web.xml文件中配置SpringMVC的前端控制器,将所有请求交给前端控制器处理,因此在url-pattern中配置了斜杠(/):

<!-- 1.配置springmvc前端控制器, 并将所有请求交给springmvc处理 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springmvc核心配置文件的位置,默认Springmvc的配置文件是在WEB-INF目录下,默认的名字为springmvc-servlet.xml,如果要放在其他目录,则需要指定如下配置:
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>

</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 斜杠表示拦截所有请求(除JSP以外) -->
<url-pattern>/</url-pattern>
</servlet-mapping>

url-pattern中配置的斜杠(/)表示将除了JSP以外的其他请求都拦截下来,交给spring的前端控制器来处理。

但是这样配置,会将对静态资源的访问也拦截下来,导致访问静态资源时,出现404(资源找不到),因为spring的前端控制器将对静态资源的访问也当成了一个controller请求,去配置对应的映射路径,这当然找不到。

比如访问:http://localhost/springmvc/home.html,由于配置的是斜杠(/),所以此时会拦截静态资源,到controller中匹配路径为/home.html的方法,此时自然是匹配不到的。

如果需要访问到静态资源,让前端控制器对静态资源的请求放行。此时可以在springmvc-config.xml文件中添加放行静态资源的配置:

<!-- 1.配置前端控制器放行静态资源(html/css/js等,否则静态资源将无法访问) -->
<mvc:default-servlet-handler/>

7、创建并实现HelloController类

1、创建com.fhy.controller.HelloController类

 2、实现HelloController类

package com.fhy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @Controller作用: 
 * (1)标识当前类属于controller层
 * (2)在spring容器扫描到springmvc的配置文件中配置的context:component-scan标签的属性base-package
 * 所指定的包路径下的类文件时(例如这里所指定的 com.tedu.controller包的类时),
 * 如果扫描到的类上有@Controller、@Service、@Component等注解时,就会自动将该类注册为Spring容器所管理的bean,
 * 即将该类的实例交给spring容器创建。
 */
@Controller
public class HelloController {
    /*
     * (1)@RequestMapping是一个用来处理请求地址映射的注解,即用于建立请求URL和处理请求的方法之间的对应关系。
     * (2)@RequestMapping注解可以在控制器类的级别和/或其中的方法的级别上使用。即可用于类或方法上.
     * (3)类的级别上的注解会将一个特定请求或者请求模式映射到一个控制器上。之后还可以另添加方法级别的注解来进一步指定到处理方法的映射关系。
     * 即用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;是请求URL的第一级访问目录,此处不写的话,就相当于应用程序的根目录;
     * 用于配置当前方法的访问路径,不能省略!
     * (4)@RequestMapping 是为当前类或者方法配置访问路径, 要求: 类上的访问路径+方法上的访问路径对于整个应用程序是不能重复的,
     * 否则就会抛异常!因为互联网上的请求URL的路径地址一定是唯一存在的。
     */
    @RequestMapping("/hello")
    public String testHello() {
        System.out.println( "hello springmvc...." );
        //return之后,可以是某一个jsp的名字(默认转发),也可以是重定向或转发到某一个方法.
        return "home";
    }
}

8、创建并实现home.jsp

在WEB-INF/pages/目录下,创建home.jsp页面。

WEB-INF/pages/home.jsp

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8">
</head>
<body>
    <h1>springmvc...home.jsp....</h1>
</body>
</html>

9、创建并实现test.jsp

在WEB-INF/pages/目录下,创建home.jsp页面。

WEB-INF/pages/test.jsp

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
    <h1>springmvc~~~test.jsp~~~</h1>
</body>
</html>

10、资源跳转处理之SpringMVC实现转发(forward)

在Servlet中,通过request对象可以实现请求转发(即资源的跳转)。同样的,springmvc也提供了请求转发的方式,具体实现如下:

需求:通过浏览器访问 testForward方法,执行testForward方法后,将请求转发到(HelloController)test, 也就是test.jsp页面。

1、在HelloController中,提供testForward方法,代码实现如下:

    /* 
     * 1、测试springmvc的转发
     * (1)如果在controller方法内部【 return “jsp的名字”】就是从当前方法
     *     转发到这个jsp (只有转发才能跳转到/WEB-INF目录中的资源)
     * (2)如果是从当前controller方法跳转到其他的controller方法
     *     此时需要 【return "forward:/资源路径"】
     *     例如: 当浏览器访问 "/testForward"时,testForward方法执行,在方法内部
     *     跳转到 "/test" 路径对应的方法(test方法)
     */
    @RequestMapping("/testForward")
    public String testForward() {
        System.out.println("testForward()执行了...即将跳转到 /test路径..");
        //转发到某一个controller方法,此处是转发到当前controller类中的test方法。
        return "forward:/test";
    }
    @RequestMapping("/test")
    public String test() {
        System.out.println("test方法执行了...即将跳转到test.jsp...");
        //转发到test.jsp,默认是转发,无需forward
        return "test"; //跳转到test.jsp
    }        

2、打开浏览器,在浏览器中输入:http://localhost/springmvc/testForward地址,访问效果如下:

 

3、forward方式相当于Servlet中的:

request.getRequestDispatcher("url").forward(request,response);

转发是一次请求,一次响应;

转发后地址栏地址没有发生变化(还是访问testForward的地址);

转发前后的request和response对象也是同一个。

11、资源跳转处理之SpringMVC实现重定向(redirect)

在Servlet中,通过response对象可以实现请求重定向(即资源的跳转)。

同样的,springmvc也提供了请求重定向的方式,具体实现如下:

需求:通过浏览器访问 testRedirect方法,执行testRedirect方法后,将请求重定向到 (HelloController)test, 也就是test.jsp页面。

或者将请求重定向到webapp目录下的home.jsp(没有被WEB-INF保护的资源);或者将请求重定向到http://www.baidu.com。

1、在HelloController中,提供testRedirect方法,代码实现如下:

    /* 
     * 2、测试springmvc的重定向
     * (1)可以从当前controller中的方法重定向到另一个controller方法
     * (2)也可以从当前controller方法重定向到其他应用的资源
     * (3)也可以从当前controller方法重定向到其他服务器内部的资源
     *         【return "redirect:/资源路径"】
     */
    @RequestMapping("/testRedirect")
    public String testRedirect() {
        System.out.println("testRedirect方法执行了..即将跳转到 /test...");
        return "redirect:/test"; //重定向到 /test
        //return "redirect:http://localhost:8080/springmvc/home.jsp";
        //return "redirect:http://www.baidu.com";
    }    

2、打开浏览器,在浏览器中输入:http://localhost/day16-springmvc/testRedirect地址,访问效果如下:

3、redirect方式相当于Servlet中的

response.sendRedirect(url);

重定向是两次请求,两次响应;

重定向后地址栏地址发生了变化(变为转发后的地址);

并且在重定向前后,request和response对象不是同一个。

12、SpringMVC 如何获取请求参数

SpringMVC中提供了参数绑定机制: 

当项目中引入springmvc框架后,所有的请求流转将由springmvc进行控制,当客户端发送的请求中包含数据(也就是请求参数)时,那么该如何在controller层获取这些参数呢?

springmvc会自动的将请求中包含的参数和方法的参数进行匹配,也就是说只要保证,请求中的参数名称和方法中的参数名称相对应(另,参数的格式也要正确),在方法中就可以使用这些参数—即请求中的参数。

基本类型参数绑定:

当需要获取客户端发送过来的少量数据时,可以在Controller中声明的方法上,通过声明方法参数对这些参数一个一个进行接收,具体示例如下:

需求:通过浏览器发请求访问Controller,并在请求中携带name、age等数据访问服务器,在服务器端的 Controller中获取这些数据。

1、在HelloController类中添加testParam1方法,用于接收基本类型的参数,代码实现如下:

  /* 
   * 1、测试springmvc的简单类型参数绑定
   * ../testParam1?name=张飞&age=20&addr=河北
   * 如何获取请求中name、age、addr的参数值?
   * 在Servlet中获取方式如下:
   *  request.getParameter("name") -- 张飞
   * 在SpringMVC框架中只需在方法上添加三个同类型、同名的形参分别为 name、age、addr
   * 用于接收请求中name、age、addr参数的值即可  
   */    
  @RequestMapping("/testParam1")
  public String testParam1(String name, Integer age, String addr) {
    System.out.println( "name="+name );
    System.out.println( "age="+age );
    System.out.println( "addr="+addr );
    return "home";
  }    

2、访问HelloController中的testParam1方法,在访问时,注意将name、age、addr参数一起发送给服务器:

 控制台输出结果为:

包装类型参数绑定:

当需要获取客户端发送过来的多个数据时,在Controller中声明的方法上,通过声明方法参数对这些数据一个一个进行接收较麻烦,可以在方法上声明对象类型的参数,通过对这些数据统一进行接收,springmvc会自动将接收过来的参数封装在对象中,具体示例如下:

1、在HelloController类中添加param2方法,用于接收对象类型的参数,代码实现如下:

    /* 
     * 2、测试springmvc的包装类型参数绑定
     * ../testParam2?name=关羽&age=30&addr=北京
     * 如何获取请求中name、age、addr的参数值?
     * 提供一个User类,在类中添加和请求参数同名的属性
     * 底层通过调用setName、setAge、setAddr方法将参数值封装到User对象中 
     */
    @RequestMapping("/testParam2")
    public String testParam2(User user) {
        System.out.println( "user.name="+user.getName() );
        System.out.println( "user.age="+user.getAge() );
        System.out.println( "user.addr="+user.getAddr() );
        return "home";
    }  

2、在springmvc/src/main/java/com.fhy.pojo包下,创建User类,声明name、age、addr属性,提供对应的set和get方法

package com.fhy.pojo;

public class User {
    private String name;
    private Integer age;
    private String addr;
    
    //无参构造函数
    public User() {    }
    
    //有参构造函数
    public User(String name, Integer age, String addr) {
        this.name = name;
        this.age = age;
        this.addr = addr;
    }

    //提供get和set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println( "setName执行了..."+name ) ;
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        System.out.println( "setAge执行了..."+age ) ;
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        System.out.println( "setAddr执行了..."+addr ) ;
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", addr=" + addr + "]";
    }
}

3、访问HelloController中的param2方法,在访问时,注意将name和age参数一起发送给服务器:

 控制台输出结果为:

日期类型参数绑定:

当需要获取客户端发送过来的日期数据时,可以在Controller中声明的方法上,通过声明为java.util包下的Date类型的方法参数对这些数据进行接收,SpringMVC对于日期类型的接收存在着一些规则,具体示例如下:

1、在HelloController类中添加testParam3方法,代码实现如下:

    /* 
     * 3、测试springmvc的日期类型参数绑定
     * ../testParam3?date=2020-4-10 16:40:39    报400错误,表示参数类型不匹配
     * ../testParam3?date=2020/4/10 16:40:39
     *     (1)400错误,是因为参数类型不匹配导致的,例如,使用Integer/int接收一个非数值,或者使用日期对象接收一个非日期格式的字符串.
     *     (2)如何获取请求中date参数的值?
     *     由于springmvc默认的日期格式是以 "/"(斜杠)分隔,所以当浏览器传递过来的日期是以斜杠分隔,springmvc可以通过参数绑定进行获取;
     *     但如果浏览器传递过来的日期是以别的符号分隔(例如:-横杠),在springmvc看来这不是一个日期,所以无法获取,就会报400错误!
     *     (3)SpringMVC获取日期类型参数时报400错误的解决方法: 
     *         1)通过浏览器传递日期参数时,不要用横杠分隔,而是用斜杠(/)分隔;
     *         2)将springmvc默认的接收的日期格式改为以横杠(-)分隔!
     */
    @RequestMapping("/testParam3")
    public String testParam3(Date date) {
        System.out.println( "date="+date );
        return "home";
    }  

2、访问HelloController中的testParam3方法,在访问时,注意将date参数一起发送给服务器:

 控制台输出结果为:

 修改springmvc默认的日期类型接收格式:

1、当访问HelloController中的testParam3方法,如果传递给服务器的日期数据是如下格式:

 从图中可以看出,如果日期参数是 yyyy-MM-dd格式(以横杠分隔)就会出现400错误,其实是因为参数格式匹配错误,由于springmvc默认的日期格式是yyyy/MM/dd(以斜杠分隔),因此如果日期参数不是yyyy/MM/dd 格式,就会出现400错误!!

2、解决方案:

在springmvc中,提供了@InitBinder注解,用于指定自定义的日期转换格式,因此,我们只需要在Controller类中添加下面的代码即可,在接收日期类型的参数时,会自动按照自定义的日期格式进行转换。

    /*
     * 4.自定义日期格式转换器:将springmvc默认以斜杠(/)分隔日期改为以横杠分隔(-).
     */
    @InitBinder
    public void InitBinder (ServletRequestDataBinder binder) {
        binder.registerCustomEditor(java.util.Date.class, 
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
    }

3、再次测试:

 控制台输出结果为:

如何获取一个参数名对应的多个参数值:

当需要获取客户端发送过来的一个参数名对应多个参数值数据时,可以在Controller中声明的方法上,通过声明为数据类型的方法参数对这些数据进行接收,具体示例如下:

1、在HelloController类中添加testParam4方法,代码实现如下:

    /*
     * 5.如何获取一个参数名对应的多个参数值
     *     /testParam04?like=篮球&like=足球&like=排球
     * 在Servlet中获取方式如下:
     *     String[] like = request.getParameterValues("like")
     * 在SpringMVC框架中只需在方法上添加一个同类型、同名的数组形参,用于接收请求中一参多值的参数的值即可.
     */
    @RequestMapping("/testParam04")
    public String testParam04( String[] like ) {
        System.out.println( Arrays.toString( like ) );
        return "home";
    }

2、在springmvc项目下/src/main/webapp目录下,创建form.html,用于测试SpringMVC接收get和post请求的一参多值类型的参数数据:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>获取请求参数</title>
</head>
<body>
<h1>GET提交</h1>
<form action="http://localhost:8080/springmvc/testParam04" method="GET">
    用户名: <input type="text" name="user"/>
    爱好: <input type="checkbox" name="like" value="篮球"/>篮球
        <input type="checkbox" name="like" value="足球"/>足球
        <input type="checkbox" name="like" value="排球"/>排球
    <input type="submit" value="提交"/>
</form>

<h1>POST提交</h1>
<form action="http://localhost:8080/springmvc/testParam04" method="POST">
    用户名: <input type="text" name="user"/>
    爱好: <input type="checkbox" name="like" value="篮球"/>篮球
        <input type="checkbox" name="like" value="足球"/>足球
        <input type="checkbox" name="like" value="排球"/>排球
    <input type="submit" value="提交"/>
</form>
</body>
</html>

3、访问http://localhost:8080/springmvc/form.html 提交如下数据参数一起发送给服务器:

 

  控制台输出结果为:

13、测试SpringMVC请求参数乱码问题

在初始SpringMVC的第4个内容里,已经讨论了乱码的解决方案,就是在web.xml中配置请求参数乱码过滤器。在配置乱码过滤器前后,可以应用一下代码进行测试:

    /* 
     * 6.测试springmvc的请求参数乱码处理:
     * (1)如果是GET提交、tomcat为8.0及以后的版本,GET提交的中文参数在获取时,是
     *     没有乱码的!
     * (2)如果是POST提交,无论哪个版本的tomcat,POST提交的中文参数在获取时,都是
     *     有乱码的, request中的解决方法为: 在获取任何参数的代码之前,添加如下代码
     *         request.setCharacterEncoding("utf-8");
     *     如果是springmvc,解决post提交的中文参数乱码问题,只需要配置一个过滤器,就可以
     *     达到一劳永逸的效果.
     *     需要在web.xml文件中启动springmvc的过滤器,解决POST提交的中文参数乱码问题!
     *     //获取请求中的 user和like对应的参数值 
     */
    @RequestMapping("/testParam05")
    public String testParam05(String user, String[] like) {
        System.out.println( "user="+user );
        System.out.println( "like="+ Arrays.toString( like ) );
        return "test";
    }    

14、springmvc响应数据

 SpringMVC响应数据的方式有很多,比如Model,ModelMap和ModelAndView等,虽然方式看似不同,但其根据多态的特性,底层调用的实现类是一样的。

这里重点讨论Model的使用,这是一个接口类型,通过接口类型去调用具体的实现类:

1.SpringMVC响应数据之Model的使用:响应基本类型数据到JSP

当请求发起访问Controller中的方法时,可以通过参数声明,在方法内使用Model。

@RequestMapping("/testModel01")
public String testModel01( Model model ) { }

Model对象实际上是一个Map集合,例如:往model中添加一个属性

model.addAttribute(String name, Object value);

其中,addAttribute方法会将属性保存到request域中,再通过转发将属性数据带到相应的JSP中,通过${}取出并显示。

示例,往Model中添加属性:

@RequestMapping("/testModel")
public String testModel(Model model){
    /* 往Model添加属性 */
    model.addAttribute("name", "马云");
    model.addAttribute("age", 20);
    return "home";
}

在home.jsp中取出属性并显示:

<body>
    <h1>hello springmvc~~~</h1>
    ${ name } <br/>
    ${ age }
</body>

2.SpringMVC响应数据之Model的使用:响应封装实体类型数据到JSP

将员工数据name、age、addr属性,封装到User对象中,并响应给客户端:在HelloController类中添加testModel01方法,用于响应实体对象类型的参数,代码实现如下:

    /*
     * 4、springmvc响应数据:封装类型数据
     * (1)如何从Servlet带数据到JSP? 答:request域对象+请求转发;
     * (2)如何从controller方法带数据到JSP? 答:Model(底层就是request域)+请求转发. 
     */
    @RequestMapping("/testModel01")
    public String testModel01( Model model ) {
        //对请求进行处理,处理的结果是一个User对象;声明一个User对象,将User对象存入Model中.
        User user = new User("张三疯",30,"北京石景山");
        /* 
         * model.addAttribute( "user", user );
         * 等价于(其底层就是),
         * request.setAttribute( "user", user );
         */
        model.addAttribute( "user", user );
        //转发到test01.jsp
        return "test01"; 
    }

3.SpringMVC响应数据之Model的使用:响应集合类型数据到JSP

将员工数据name、age、addr属性,封装到User对象中,并添加到ArrayList集合中,响应给客户端:在HelloController类中添加testModel02方法,用于响应集合类型的参数,代码实现如下:

    @RequestMapping("/testModel02")
    public String testModel02( Model model ) {
        //对请求进行处理,处理的结果是一个List<User>对象,声明一个List集合,并将集合存入Model域中.
        List<User> userList = new ArrayList();
        userList.add( new User("张三疯", 30, "北京石景山") );
        userList.add( new User("李四", 38, "北京昌平") );
        /*
         * model.addAttribute( "list", userList );
         * 就相当于(其底层就是)
         * request.setAttribute( "user", userList );
         */
        model.addAttribute( "list", userList );
        //转发到test01.jsp
        return "test01"; 
    } 

4.SpringMVC响应数据之Model的使用:在JSP中获取服务端SpringMVC的Model域传过来的数据:

在springmvc/src/main/webapp/WEB-INF/pages目录下,创建test01.jsp页面,对SpringMVC响应的封装实体类型数据和响应集合类型的数据都用test02.jsp来进行数据展显,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
    <h1>springmvc~~~test.jsp~~~</h1>
    <%-- 此处必须百分号的注释,即JSP注释,不能使用HTML注释(<!-- 感叹号注释 -->),否则$会被执行,而空的${}会报错 --%>
    <%-- JSP可以用el表达式取值(例如:${user.getXxx}),可以从 request域 中获取数据 --%>
    ${ user.getName() }
    ${ user.getAge() }
    ${ user.getAddr() }
    <hr/>
    <%-- el表达式取值,${user.getXxx}中的get字符可以省略,简写为${user.xxx} --%>
    ${ user.name }
    ${ user.age }
    ${ user.addr }
    <hr/>
    <%-- 通过${}从request域中获取List集合 --%>
    ${ list[0] } <br/>
    ${ list[1] } <br/>    
</body>
</html>

5.SpringMVC响应数据之Model的使用:测试服务端SpringMVC的Model域传递的数据是否成功:

1、访问http://localhost:8080/springmvc/testModel01 获取Model域中的对象类型数据,页面响应如下内容即测试成功:

1、访问http://localhost:8080/springmvc/testModel02 获取Model域中的集合类型数据,页面响应如下内容即测试成功:

 that is all   !!!!!

原文地址:https://www.cnblogs.com/HarryVan/p/13374122.html