首页 > 技术文章 > springMVC之原理,接收数据和响应数据

liyunfeng-deng 2019-01-17 17:45 原文

第一:要了解springMVC的运行原理

第二:我们为什么要使用springmvc?

那就是为了替代我们用servlet来处理和响应请求,虽然它的底层依然是servlet,但是利用框架不仅能够减少我们的代码量,还能让我们更加专注于业务逻辑。

第二:响应的方式:一种是配置文件,另一种是注解

这里先讲解配置文件方式的形式:如果我们自己定义了controller类,那么与直接使用框架中的是不同的

在这里我们先自己创建一个controller类

controller类代码:

 1 /**
 2  * 
 3  */
 4 package com.sxt.controller;
 5 
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 import org.springframework.web.servlet.ModelAndView;
10 import org.springframework.web.servlet.mvc.Controller;
11 
12 /**
13  * @author ASUS
14  * 如果使用的是自定义的controller就需要实现一个叫做controller的接口
15  *
16  */
17 public class MyController implements Controller{
18     @Override
19     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
20         // TODO Auto-generated method stub
21         System.out.println("我被执行了");
22         ModelAndView mv=new ModelAndView();
23         mv.setViewName("index.jsp");
24         return mv;
25     }
26 }

在使用springmvc的时候我们一共需要两个配置文件:一个是专门的springmvc配置文件是为了告诉我们的spring框架的dispartcherServlet中心处理器,要帮助我们做的工作;另一个是web项目的xml文件(该文件是每一个web项目创建的时候都会生成的),这里是将我们的springmvc框架和我们的web项目关联起来,有了这两个配置文件,springmvc框架就可以很好地为我们的项目服务了。

spring-mvc配置文件(名字自己随便起,但是该文件必须和web项目的包处于同一级文件夹下)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 5  http://www.springframework.org/schema/beans/spring-beans.xsd">
 6     
 7     <!-- 处理器映射器 将bean的name作为url进行查找 ,
 8                   需要在配置Handler时指定beanname(就是url) 所有的映射器都实现 
 9          HandlerMapping接口。
10      -->
11     <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
12 
13     <!-- 配置 Controller适配器 -->
14     <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
15     
16     <!-- 配置自定义的 controller 表示将该类交给spring管理 -->
17     <bean class="com.sxt.controller.MyController" name="/user.sxt"></bean>
18 </beans>

web.xml配置文件的代码:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
 3   <display-name>springmvc-01helloworld</display-name>
 4   <welcome-file-list>
 5     <welcome-file>index.html</welcome-file>
 6     <welcome-file>index.htm</welcome-file>
 7     <welcome-file>index.jsp</welcome-file>
 8     <welcome-file>default.html</welcome-file>
 9     <welcome-file>default.htm</welcome-file>
10     <welcome-file>default.jsp</welcome-file>
11   </welcome-file-list>
12   <!-- 前端控制器也叫作中心控制器;功能是任意的请求都会交给springmvc下的DispatcherServlet进行处理 -->
13   <servlet>
14   <servlet-name>spring-mvc</servlet-name>
15   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
16   <!-- 这里的配置是为了关联springmvc -->
17   <init-param>
18   <param-name>contextConfigLocation</param-name>
19   <param-value>classpath:spring-mvc.xml</param-value>
20   </init-param>
21   </servlet>
22   <servlet-mapping>
23   <servlet-name>spring-mvc</servlet-name>
24   <url-pattern>/</url-pattern>
25   </servlet-mapping>
26 </web-app>

需要导入的jar包:

在浏览器器中输入地址进行验证:http://localhost:8080/springmvc-01helloworld/user.sxt;就可以看到结果

响应方式二之使用注解;上面那种方式我们需要在配置文件中写一大堆的配置信息,而且自己创建的controller也只能一次处理一种的请求,如果我们需要多种请求(最起码也是增删查改吧),那么就需要多创建几个controller,增加了代码量。而注解就很好的解决了这个问题

使用注解的controller代码:在这里一定要理解这几个注解所代表的含义是什么

 1 /**
 2  * 
 3  */
 4 package com.sxt.controller;
 5 import org.springframework.stereotype.Controller;
 6 import org.springframework.web.bind.annotation.RequestMapping;
 7 import org.springframework.web.servlet.ModelAndView;
 8 /**
 9  * @author ASUS
10  * 这里不使用自己定义的controller,
11  *
12  */
13 @Controller
14 //表示将该类交给spring容器进行管理
15 @RequestMapping("/user")//表示的是我们请求的是哪个资源下的方法,起了一个别名
16 public class MyController {
17     @RequestMapping("/add")
18     public ModelAndView add() {
19         System.out.println("我执行了1");
20         ModelAndView mc=new ModelAndView();
21         mc.setViewName("/index.jsp");
22         return mc;    
23     }
24     @RequestMapping("/query")
25     public ModelAndView query() {
26         System.out.println("我执行了2");
27         ModelAndView mc=new ModelAndView();
28         mc.setViewName("/index.jsp");
29         return mc;
30     }
31 }

我们还要在springmvc.xml中开启扫描和开启注解,代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:mvc="http://www.springframework.org/schema/mvc"
 6     xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
 7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 9     
10     <!-- 开启注解 -->
11     <mvc:annotation-driven></mvc:annotation-driven>
12     <!-- 开启扫描 -->
13     <context:component-scan base-package="com.sxt.controller"></context:component-scan>
14 </beans>

web.xml配置文件的代码:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
 3   <display-name>springmvc-02-annotation</display-name>
 4   <welcome-file-list>
 5     <welcome-file>index.html</welcome-file>
 6     <welcome-file>index.htm</welcome-file>
 7     <welcome-file>index.jsp</welcome-file>
 8     <welcome-file>default.html</welcome-file>
 9     <welcome-file>default.htm</welcome-file>
10     <welcome-file>default.jsp</welcome-file>
11   </welcome-file-list>
12   <!-- 中心控制器 -->
13   <servlet>
14   <servlet-name>spring-mvc</servlet-name>
15   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
16   <!-- 关联springmvc配置文件:因为我们的中心控制器要使用里面的处理器 -->
17   <init-param>
18   <param-name>contextConfigLocation</param-name>
19   <param-value>classpath:spring-mvc.xml</param-value>
20   </init-param>
21   </servlet>
22   <servlet-mapping>
23   <servlet-name>spring-mvc</servlet-name>
24   <url-pattern>/</url-pattern>
25   </servlet-mapping>
26 </web-app>

效果图如下:这里的controller的两个方法分别模仿的是添加和查询的响应

当我们使用了注解以后,我们如果在不添加新的功能的情况下(后面会有涉及,比如获取用户请求的时间数据,需要一个转换器;处理中文乱码问题需要一个过滤器配置),我们的配置文件是不用改变的,这样就大大的方便了我们的开发。

观察中心处理器的源码可以知道:

 1 # Default implementation classes for DispatcherServlet's strategy interfaces.
 2 # Used as fallback when no matching beans are found in the DispatcherServlet context.
 3 # Not meant to be customized by application developers.
 4 
 5 org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
 6 
 7 org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
 8 
 9 org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
10     org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
11 处理器映射器:有两个一个所以使用的时候需要明确指出是哪一个
12 org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
13     org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
14     org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
15 处理器适配器有三个:一个是转门处理httP协议的请求,一个是自己定义controller的控制器处理适配器,还有一个是注解的适配器
16 org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
17     org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
18     org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
19 
20 org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
21 
22 org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
23 这里是视图解析器,只有一个,不配置的时候会默认使用该解析器
24 org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

由该源码可知:在springmvc中一共有四个重要的组件:

一个是中心处理器:DispatcherServlet;处理用户的请求,降低了组件之间的耦合性,起调配作用

二个是处理器映射器:负责根据用户请求找到处理器返回给中心处理器,提供了不同的映射方式:配置映射,注解映射,实现接口映射(自己定义controller)

三个是处理器适配器:找到专门的controller来处理用户的请求,并返回一个ModleAndView给中心处理器

四个是视图解析器:负责将处理结果解析生成View视图,然后渲染之后响应给用户端。

第三:具体的springmvc响应请求的方式

基本数据类型

 1 /**
 2      * 接收基本的数据类型的参数
 3      * 要求参数的名称必须与形参一致
 4      */
 5     @RequestMapping("/fun1")
 6     @ResponseBody
 7     public void fun1(Integer id ,String name,String password) {
 8         System.out.println(id+","+name+","+password);
 9     }
10     /**
11      * 接收基本的数据类型的参数
12      * 如果想要使参数名称和形参不一致;可以利用一个注解@RequestParam
13      */
14     @RequestMapping("/fun3")
15     @ResponseBody
16     public void fun3(@RequestParam("ids")Integer id ,
17             @RequestParam("username")String name,
18             @RequestParam("pass")String password) {
19         System.out.println(id+","+name+","+password);
20     }
21     /**
22      * 接收基本的数据类型的参数
23      * 如果想要使参数名称和形参不一致;可以利用一个注解@RequestParam
24      * 但是加了这个注解以后;该形参自动提升为必须传入的参数;如果想改变这种状态,有两种方式
25      * 方式一:required=false
26      */
27     @RequestMapping("/fun4")
28     @ResponseBody
29     public void fun4(@RequestParam("ids")Integer id ,
30             @RequestParam(value="username",required=false)String name,
31             @RequestParam("pass")String password) {
32         System.out.println(id+","+name+","+password);
33     }
34     /**
35      * 接收基本的数据类型的参数
36      * 如果想要使参数名称和形参不一致;可以利用一个注解@RequestParam
37      * 但是加了这个注解以后;该形参自动提升为必须传入的参数;如果想改变这种状态,有两种方式
38      * 方式一:required=false
39      * 方式二:设置一个默认值:defaultValue="aaaa";但是这样的方法不可取
40      */
41     @RequestMapping("/fun5")
42     @ResponseBody
43     public void fun5(@RequestParam("ids")Integer id ,
44             @RequestParam(value="username",defaultValue="aaaa")String name,
45             @RequestParam("pass")String password) {
46         System.out.println(id+","+name+","+password);
47     }

对象

1 /**
2      * 接收简单对象的数据类型的参数;可以直接输出
3      */
4     @RequestMapping("/fun2")
5     @ResponseBody
6     public void fun2(Book book) {
7         System.out.println(book);
8     }

对象代码:

 1 /**
 2  * 
 3  */
 4 package com.sxt.bean;
 5 
 6 /**
 7  * @author ASUS
 8  *
 9  */
10 public class Book {
11     private int id;
12     private String name;
13     private String author;
14     public int getId() {
15         return id;
16     }
17     public void setId(int id) {
18         this.id = id;
19     }
20     public String getName() {
21         return name;
22     }
23     public void setName(String name) {
24         this.name = name;
25     }
26     public String getAuthor() {
27         return author;
28     }
29     public void setAuthor(String author) {
30         this.author = author;
31     }
32     @Override
33     public String toString() {
34         return "Book [id=" + id + ", name=" + name + ", author=" + author + "]";
35     }
36     
37     
38 
39 }

jsp代码:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3     <%
 4 String path = request.getContextPath();
 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
 6 %>
 7 <!DOCTYPE html>
 8 <html>
 9 <head>
10  <base href="<%=basePath%>">
11 <meta charset="UTF-8">
12 <title>Insert title here</title>
13 </head>
14 <body>
15 <form action="fun2" method="post">
16   <table>
17     <tr>
18      <td>编号</td>
19      <td><input type="text" name="id"></td>
20     </tr>
21     <tr>
22      <td>书名</td>
23      <td><input type="text" name="name"></td>
24     </tr>
25     <tr>
26      <td>作者</td>
27      <td><input type="text" name="author"></td>
28     </tr>
29   </table>
30    <input type="submit" value="提交">
31 </form>
32 </body>
33 </html>

复杂对象类型的参数:即对象里面的属性还有对象的参数类型

对象代码:

 1 /**
 2  * 
 3  */
 4 package com.sxt.bean;
 5 
 6 /**
 7  * @author ASUS
 8  *
 9  */
10 public class Book {
11     private int id;
12     private String name;
13     private Author author;
14     public int getId() {
15         return id;
16     }
17     public void setId(int id) {
18         this.id = id;
19     }
20     public String getName() {
21         return name;
22     }
23     public void setName(String name) {
24         this.name = name;
25     }
26     public Author getAuthor() {
27         return author;
28     }
29     public void setAuthor(Author author) {
30         this.author = author;
31     }
32     @Override
33     public String toString() {
34         return "Book [id=" + id + ", name=" + name + ", author=" + author + "]";
35     }
36     
37     
38 
39 }
 1 /**
 2  * 
 3  */
 4 package com.sxt.bean;
 5 
 6 /**
 7  * @author ASUS
 8  *
 9  */
10 public class Author {
11     private int age;
12     private String name;
13     private String sex;
14     public int getAge() {
15         return age;
16     }
17     public void setAge(int age) {
18         this.age = age;
19     }
20     public String getName() {
21         return name;
22     }
23     public void setName(String name) {
24         this.name = name;
25     }
26     public String getSex() {
27         return sex;
28     }
29     public void setSex(String sex) {
30         this.sex = sex;
31     }
32     @Override
33     public String toString() {
34         return "Author [age=" + age + ", name=" + name + ", sex=" + sex + "]";
35     }
36     
37 
38 }

controller代码:

 1 /**
 2      * 接收复杂对象的数据类型:即对象里面的属性还有对象
 3      * 这里要注意如何去将另一个对象的属性赋值给一个对象的属性:通过存取器
 4      */
 5     @RequestMapping("/fun6")
 6     @ResponseBody
 7     public void fun6(Book book ) {
 8         System.out.println(book );
 9     }
10     

jsp代码:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3     <%
 4 String path = request.getContextPath();
 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
 6 %>
 7 <!DOCTYPE html>
 8 <html>
 9 <head>
10  <base href="<%=basePath%>">
11 <meta charset="UTF-8">
12 <title>Insert title here</title>
13 </head>
14 <body>
15 <form action="fun6" method="post">
16   <table>
17     <tr>
18      <td>编号</td>
19      <td><input type="text" name="id"></td>
20     </tr>
21     <tr>
22      <td>书名</td>
23      <td><input type="text" name="name"></td>
24     </tr>
25     <tr>
26    <td>作者年龄</td>
27    <td><input type="text" name="authoer.age"></td>
28     </tr>
29     <tr>
30    <td>作者姓名</td>
31    <td><input type="text" name="authoer.name"></td>
32     </tr>
33     <tr>
34    <td>作者性别</td>
35    <td><input type="text" name="authoer.sex"></td>
36     </tr>
37   </table>
38    <input type="submit" value="提交">
39 </form>
40 </body>
41 </html>

两个配置文件的代码参考注解绑定基本参数或者和注解响应请求里面的

数组类型:例如在复选框中,我们不知道选择的类型有几个,这时候可以用数组来存储复选框中的数据

jsp代码:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3     <%
 4 String path = request.getContextPath();
 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
 6 %>
 7 <!DOCTYPE html>
 8 <html>
 9 <head>
10  <base href="<%=basePath%>">
11 <meta charset="UTF-8">
12 <title>Insert title here</title>
13 </head>
14 <body>
15 <form action="fun1" method="post">
16         <table>
17             <tr>
18                 <td>用户名</td>
19                 <td><input type="text" name="username"></td>
20             </tr>
21             <tr>
22                 <td>用户密码</td>
23                 <td><input type="password" name="password"></td>
24             </tr>
25             <tr>
26                 <td>兴趣爱好</td>
27                 <td><input type="checkbox" name="favorites" value="zuqiu">足球
28                     <input type="checkbox" name="favorites" value="lanqiu">篮球 <input
29                     type="checkbox" name="favorites" value="pingpang">乒乓球</td>
30             </tr>
31             <tr>
32                 <td><input type="submit" value="注册"></td>
33             </tr>
34         </table>
35     </form>
36 </body>
37 </html>

controller代码:

 1 /**
 2      * 获取请求数据 的数组类型;在形参中可以用数组来接收用户的请求数据
 3      */
 4     @RequestMapping("/fun1")
 5     @ResponseBody
 6     public void fun1(String username,String password,String [] favorites) {
 7         System.out.println(username+","+password);
 8         for (String f : favorites) {
 9             System.out.println(f);
10         }
11     }

集合类型:如果在controller中使用集合类型在形参中来接收用户的请求数据会有什么反应呢?

会报错,这里说明不能使用集合在controller中来接收用户的请求的数据

 

controller代码:

1 /**
2      * 获取请求数据 的集合类型:这里会报错,说明不能用集合在形参中类型来接收用户的请求数据
3      */
4     @RequestMapping("/fun2")
5     @ResponseBody
6     public void fun2(String username,String password,List<String> favorites) {
7         System.out.println(username+","+password+","+favorites);
8         
9     }

如果将集合数据类型放在对象中能不能接收呢?

答案是:能。说明集合不可以在形参中使用但是可以在对象中使用

controller代码:

 1 /**
 2      * 获取请求数据 的集合类型:这里是在对象中使用集合来存储数据类型
 3      * 这里说明将集合数据类型放在对象中可以接收,没有错误
 4      */
 5     @RequestMapping("/fun3")
 6     @ResponseBody
 7     public void fun3(User user) {
 8         System.out.println(user);
 9         
10     }

对象代码:

 1 /**
 2  * 
 3  */
 4 package com.sxt.bean;
 5 
 6 import java.util.List;
 7 
 8 /**
 9  * @author ASUS
10  *
11  */
12 public class User {
13     private String username;
14     private String password;
15     private List<String> favorites;
16     public String getUsername() {
17         return username;
18     }
19     public void setUsername(String username) {
20         this.username = username;
21     }
22     public String getPassword() {
23         return password;
24     }
25     public void setPassword(String password) {
26         this.password = password;
27     }
28     public List<String> getFavorites() {
29         return favorites;
30     }
31     public void setFavorites(List<String> favorites) {
32         this.favorites = favorites;
33     }
34     @Override
35     public String toString() {
36         return "User [username=" + username + ", password=" + password + ", favorites=" + favorites + "]";
37     }
38     
39 
40 }

jsp代码:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3     <%
 4 String path = request.getContextPath();
 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
 6 %>
 7 <!DOCTYPE html>
 8 <html>
 9 <head>
10  <base href="<%=basePath%>">
11 <meta charset="UTF-8">
12 <title>Insert title here</title>
13 </head>
14 <body>
15 <form action="fun3" method="post">
16         <table>
17             <tr>
18                 <td>用户名</td>
19                 <td><input type="text" name="username"></td>
20             </tr>
21             <tr>
22                 <td>用户密码</td>
23                 <td><input type="password" name="password"></td>
24             </tr>
25             <tr>
26                 <td>兴趣爱好</td>
27                 <td><input type="checkbox" name="favorites" value="zuqiu">足球
28                     <input type="checkbox" name="favorites" value="lanqiu">篮球 <input
29                     type="checkbox" name="favorites" value="pingpang">乒乓球</td>
30             </tr>
31             <tr>
32                 <td><input type="submit" value="注册"></td>
33             </tr>
34         </table>
35     </form>
36 </body>
37 </html>

那么如果对象中有数组属性能不能被接收呢?

答案是:能

controller代码:

 1 /**
 2      * 获取请求数据 的数组类型:这里是在对象中使用数组来存储数据类型
 3      * 这里说明将数组数据类型放在对象中可以接收,没有错误
 4      */
 5     @RequestMapping("/fun4")
 6     @ResponseBody
 7     public void fun4(User user) {
 8         System.out.println(user);
 9         
10     }

对象代码:

 1 /**
 2  * 
 3  */
 4 package com.sxt.bean;
 5 
 6 import java.util.Arrays;
 7 import java.util.List;
 8 
 9 /**
10  * @author ASUS
11  *
12  */
13 public class User {
14     private String username;
15     private String password;
16     private String[] favorites;
17     public String getUsername() {
18         return username;
19     }
20     public void setUsername(String username) {
21         this.username = username;
22     }
23     public String getPassword() {
24         return password;
25     }
26     public void setPassword(String password) {
27         this.password = password;
28     }
29     
30     public String[] getFavorites() {
31         return favorites;
32     }
33     public void setFavorites(String[] favorites) {
34         this.favorites = favorites;
35     }
36     @Override
37     public String toString() {
38         return "User [username=" + username + ", password=" + password + ", favorites=" + Arrays.toString(favorites)
39                 + "]";
40     }
41     
42     
43 
44 }

jsp代码参照上面的就可以了。

总结:在对象和形参中都可以使用数组来接收数据,在对象中也可以使用集合来接收数据,但是在形参中不能使用集合去接收数据,否则报服务器错误。

时间类型:

当不输入时间类型的时候不会报错:

如果输入时间类型的话:

原因是:绑定的数据与传输的数据不一致,绑定的是date类型的,而传输的是string类型的;绑定出错

解决问题:

方式一:将date类型---》string 类型---》在转换为date类型;做一个转换操作,即转换器

controller代码:

 1 /**
 2      *传输时间类型的数据
 3      * 
 4      */
 5     @RequestMapping("/fun5")
 6     @ResponseBody
 7     public void fun5(User user) {
 8         System.out.println(user);
 9         
10     }

转换器代码:

 1 /**
 2  * 
 3  */
 4 package com.sxt.bean;
 5 
 6 import java.text.ParseException;
 7 import java.text.SimpleDateFormat;
 8 import java.util.Date;
 9 
10 import org.springframework.core.convert.converter.Converter;
11 
12 /**
13  * @author ASUS
14  * 注意的问题:一个是继承的接口来自spring框架的core的核心包,而不是cglib包下面的
15  * 二参数问题:将S类型转换为T类型的数据
16  * 三:要是自己写的转换器起作用必须在配置文件中配置
17  *
18  */
19 public class MyConvert implements Converter<String, Date> {
20     @Override
21     public Date convert(String s) {
22         SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd");
23         try {
24             return  sdf.parse(s);
25         } catch (ParseException e) {
26             // TODO Auto-generated catch block
27             e.printStackTrace();
28         }
29         return null;
30     }
31 
32 }

spring-mvc配置文件代码:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:mvc="http://www.springframework.org/schema/mvc"
 6     xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
 7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 9     
10     <!-- 开启注解 -->
11     <mvc:annotation-driven conversion-service="formattingConversionServiceFactoryBean"></mvc:annotation-driven>
12     <!-- 开启扫描 -->
13     <context:component-scan base-package="com.sxt.controller"></context:component-scan>
14     <!-- 配置 视图解析器 -->
15     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
16         <!-- 配置前后缀 
17         <property name="prefix" value="/book"/>
18         <property name="suffix" value=".jsp"/>
19         -->
20     </bean>
21     
22     <!-- 配置自定义的转换器 -->
23     <bean id="formattingConversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
24         <property name="converters">
25             <set>
26                 <bean class="com.sxt.bean.MyConvert"></bean>
27             </set>
28         </property>    
29     </bean>
30 </beans>

总结:获取用户请求数据的时候,如果是基本数据类型可以直接获取,但是要注意包装类(引用数据类类型)和基本类型的的区别?包装类可以为空,基本数据类型不能为空

第二还要注意的就是形参和要求的参数类型不一致的时候的解决。

对象:分为简单对象(直接获取输出即可),复杂对象(对象里面套对象)通过存取器来获取数据

数组:在对象和形参中都可以用来获取数据

集合:在形参中不可以使用来获取数据,在对象中可以用来获取数据。

时间类型:要写一个转换器。

在springmvc中最主要的一是注解和配置文件的使用;

二是如果自己写了新的类来处理业务,那么必须在配置文件进行配置,否则不能使用。

如果想往动态页面中传值,那么可以使用以下三种方式:

map,ModelMap,Model

代码如下:

 1 /**
 2  * 
 3  */
 4 package com.sxt.controller;
 5 
 6 
 7 
 8 import java.util.Map;
 9 
10 import org.springframework.stereotype.Controller;
11 import org.springframework.ui.Model;
12 import org.springframework.ui.ModelMap;
13 import org.springframework.web.bind.annotation.RequestMapping;
14 /**
15  * @author ASUS
16  * 如果想往动态页面传值:可以用一下三种方式
17  *  
18  *
19  */
20 @Controller
21 public class MyController {
22     /**
23      *通过map传值
24      * @param map
25      * @return
26      */
27     @RequestMapping("/fun1")
28     public String fun1(Map<String, Object> map) {
29         map.put("msg", "map-->value");
30         System.out.println("-----------");
31         return "/index.jsp";
32         
33     }
34     /**
35      *通过model传值
36      * @param map
37      * @return
38      */
39     @RequestMapping("/fun2")
40     public String fun2(Model m) {
41         m.addAttribute("msg","model-->value");
42         System.out.println("-----------");
43         return "/index.jsp";
44         
45     }
46     /**
47      *通过modelMap传值
48      * @param map
49      * @return
50      */
51     @RequestMapping("/fun3")
52     public String fun3(ModelMap m) {
53         m.addAttribute("msg","ModelMap-->value");
54         System.out.println("-----------");
55         return "/index.jsp";
56         
57     }
58     
59 }

jsp页面代码:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3     <%
 4 String path = request.getContextPath();
 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
 6 %>
 7 <!DOCTYPE html>
 8 <html>
 9 <head>
10  <base href="<%=basePath%>">
11 <meta charset="UTF-8">
12 <title>Insert title here</title>
13 </head>
14 <body>
15 我是一个码农!!!!!<br>
16 request:${requestScope.msg}<br>
17 session:${sessionScope.msg}<br>
18 
19 </body>
20 </html>

结果如下:

由上图可知:这三种传值方式都是request传值

如果想用session传值怎么办?

直接在controller类的前面加一个注解,将传值方式提升为session传值,这个时候request和session都会有值了。

代码如下:

 1 /**
 2  * 
 3  */
 4 package com.sxt.controller;
 5 
 6 
 7 
 8 import java.util.Map;
 9 
10 import org.springframework.stereotype.Controller;
11 import org.springframework.ui.Model;
12 import org.springframework.ui.ModelMap;
13 import org.springframework.web.bind.annotation.RequestMapping;
14 import org.springframework.web.bind.annotation.SessionAttributes;
15 /**
16  * @author ASUS
17  * 如果想往动态页面传值:可以用一下三种方式
18  * 如果想改变成session传值: 
19  *
20  */
21 @Controller
22 @SessionAttributes("msg")
23 public class MyController {
24     /**
25      *通过map传值
26      * @param map
27      * @return
28      */
29     @RequestMapping("/fun1")
30     public String fun1(Map<String, Object> map) {
31         map.put("msg", "map-->value");
32         System.out.println("-----------");
33         return "/index.jsp";
34         
35     }
36     /**
37      *通过model传值
38      * @param map
39      * @return
40      */
41     @RequestMapping("/fun2")
42     public String fun2(Model m) {
43         m.addAttribute("msg","model-->value");
44         System.out.println("-----------");
45         return "/index.jsp";
46         
47     }
48     /**
49      *通过modelMap传值
50      * @param map
51      * @return
52      */
53     @RequestMapping("/fun3")
54     public String fun3(ModelMap m) {
55         m.addAttribute("msg","ModelMap-->value");
56         System.out.println("-----------");
57         return "/index.jsp";
58         
59     }
60     
61 }

jsp的代码不变,一定要注意两者传值的区别。

结果如下:

springmvc的中文乱码问题解决:

如果是在基本的servlet处理请求的时候,我们可以在设置编码方式,但是这里没有给我们暴露相关的request,但是却给我们暴露了一个过滤器,因此我们只需要在web.xml文件中配置一个中文乱码问题的过滤器就可以了》

代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
 3   <display-name>web-springmvc-hello</display-name>
 4   <welcome-file-list>
 5     <welcome-file>index.html</welcome-file>
 6     <welcome-file>index.htm</welcome-file>
 7     <welcome-file>index.jsp</welcome-file>
 8     <welcome-file>default.html</welcome-file>
 9     <welcome-file>default.htm</welcome-file>
10     <welcome-file>default.jsp</welcome-file>
11   </welcome-file-list>
12   <servlet>
13   <servlet-name>spring-mvc</servlet-name>
14   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
15   <!-- 关联springmvc配置文件:因为我们的中心控制器要使用里面的处理器 -->
16   <init-param>
17   <param-name>contextConfigLocation</param-name>
18   <param-value>classpath:spring-mvc.xml</param-value>
19   </init-param>
20   </servlet>
21   <servlet-mapping>
22   <servlet-name>spring-mvc</servlet-name>
23   <url-pattern>/</url-pattern>
24   </servlet-mapping>
25   <!-- spring框架提供的字符集过滤器 -->
26     <!-- spring Web MVC框架提供了org.springframework.web.filter.CharacterEncodingFilter用于解决POST方式造成的中文乱码问题 -->
27     <filter>
28         <filter-name>encodingFilter</filter-name>
29         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
30         <init-param>
31             <param-name>encoding</param-name>
32             <param-value>UTF-8</param-value>
33         </init-param>
34     </filter>
35     <filter-mapping>
36         <filter-name>encodingFilter</filter-name>
37         <url-pattern>/*</url-pattern>
38     </filter-mapping>
39   
40 </web-app>

 

推荐阅读