`

SpringMVC数据绑定全面示例(复杂对象,数组等)

 
阅读更多
http://www.xdemo.org/springmvc-data-bind/
首先贴出Controller的全部内容
/**
 * @author <a href="http://www.xdemo.org">xdemo.org</a>
 */
@Controller
@RequestMapping(value="/request")
public class RequestParamController {
                
               /**
                * 最简的配置,不是用@RequestParam,效果和get2一样,默认required=false
                * 请求方式不限
                * @param p1
                * @param map
                */
               @RequestMapping(value="get0")
               public void get0(String p1,ModelMap map){
                               map.addAttribute("p1", p1);//往页面传递
               }
                
               /**
                * value="p1"表示参数名称<br>
                * required=true表示如果没有传递参数"p1",则会报400参数异常<br>
                * 使用void表示约定的路径,即request/get1.jsp
                * @param p1
                * @param map
                */
               @RequestMapping(value="get1",method=RequestMethod.GET)
               public void get1(@RequestParam(value="p1",required=true)String p1,ModelMap map){
                               map.addAttribute("p1", p1);//往页面传递
               }
                
               /**
                * 和get1不同的是,p1这个参数不一定非得需要,即使不给这个参数,也可以正常运行<br>
                * 返回String是视图的名称,只要将map赋值,给的值也会带到前抬
                * @param p1
                * @param map
                * @return
                */
               @RequestMapping(value="get2",method=RequestMethod.GET)
               public String get2(@RequestParam(value="p1",required=false)String p1,ModelMap map){
                               map.addAttribute("p1", p1);//往页面传递
                               return "request/get2";
               }
                
               /**
                * 和get2不同的是,返回的对象是ModelAndView
                * 表示绑定了视图和数据的对象,数据就是ModelMap中的Key-Value
                * @param p1
                * @param map
                * @return
                */
               @RequestMapping(value="get3",method=RequestMethod.GET)
               public ModelAndView get3(@RequestParam(value="p1",required=false)String p1,ModelMap map){
                               map.addAttribute("p1", p1);
                               return new ModelAndView("request/get2",map);
               }
                
               /**
                * 跳转到页面
                * @throws NoSuchAlgorithmException 
                */
               @RequestMapping("userForm")
               public String userForm(HttpServletResponse response) throws NoSuchAlgorithmException{
                               CookieUtils.writeCookie(response, -1, "x", "dddddddddddddd");
                               return "request/userForm";
               }
                
               /**
                * 绑定数据到User对象,支持Map,Set,List,Array等,但是需要使用下标,不是很灵活
                * 请查看user2的写法
                * @param user
                * @param map
                */
               @RequestMapping(value="user")
               public void user(User user,ModelMap map){
                               map.addAttribute("user", user);
               }
                
               /**
                * 这里可以接受List,Array,Set等,写法是一样的,注意前端写法<br>
                * 另外这个必须要使用MappingJacksonHttpMessageConverter这个消息转换器
                * 请看我上面的配置
                * @param user
                * @return
                */
               @ResponseBody
               @RequestMapping("user2")
               public String user2(@RequestBody List<User> user){
                               System.out.println(user.size());
                               return "";
               }
                
               /**
                * 这个方法只支持POST
                * @param s
                * @return
                */
               @ResponseBody
               @RequestMapping("array")
               public String array(@RequestBody String[] s){
                               System.out.println(s.length);
                               return "";
               }
                
               /**
                * 这个比较奇葩,来自一位朋友的写法,即.xxx/5,4这样的请求,SpringMVC竟然也是支持的
                * @param id
                * @return
                */
               @ResponseBody
               @RequestMapping(value="array/{id}",method=RequestMethod.GET)
               public String array2(@PathVariable("id")Long[] id){
                               System.out.println(id.length);
                               return "array length:"+id.length+"";
               }
                
               /**
                * 一个表单对应多个Bean对象,这些Bean中有相同的属性,那么需要在分装他们的一个整体的对象
                * 使之支持object.property的表达式
                * @param c
                */
               @ResponseBody
               @RequestMapping("complex")
               public void complexObject(C c){
                               System.out.println(c.getA().getX());
                               System.out.println(c.getB().getX());
                                
               }
                
               /**
                * 读取Cookie的值
                * @param x
                * @return
                */
               @ResponseBody
               @RequestMapping("cookie")
               public String cookie(@CookieValue("x")String x){
                               return x;
               }
                
}

这种方式支持get和post,参数可选
/**
* 最简的配置,不是用@RequestParam,效果和get2一样,默认required=false
* 请求方式不限
* @param p1
* @param map
*/
@RequestMapping(value="get0")
public void get0(String p1,ModelMap map){
       map.addAttribute("p1", p1);//往页面传递
}

访问方式简单的比如http://localhost:8080/springmvc-param/request/get0?p1=xxx。

这种方式支持get,参数必须
/**
* value="p1"表示参数名称<br>
* required=true表示如果没有传递参数"p1",则会报400参数异常<br>
* 使用void表示约定的路径,即request/get1.jsp
* @param p1
* @param map
*/
@RequestMapping(value="get1",method=RequestMethod.GET)
public void get1(@RequestParam(value="p1",required=true)String p1,ModelMap map){
       map.addAttribute("p1", p1);//往页面传递
}

这种方式和第一种不同的是,指定了访问访问必须为GET,而且参数是必须的,可以通过如下方式访问这个地址:http://localhost:8080/springmvc-param/request/get1?p1=xxxx。

这种方式仅支持GET,参数可选
/**
* 和get1不同的是,p1这个参数不一定非得需要,即使不给这个参数,也可以正常运行<br>
* 返回String是视图的名称,只要将map赋值,给的值也会带到前抬
* @param p1
* @param map
* @return
*/
@RequestMapping(value="get2",method=RequestMethod.GET)
public String get2(@RequestParam(value="p1",required=false)String p1,ModelMap map){
       map.addAttribute("p1", p1);//往页面传递
       return "request/get2";
}

这个方法和第二种唯一不同的就是参数是可选的,其他没有不同。

这种方式仅支持GET,参数可选
/**
* 和get2不同的是,返回的对象是ModelAndView
* 表示绑定了视图和数据的对象,数据就是ModelMap中的Key-Value
* @param p1
* @param map
* @return
*/
@RequestMapping(value="get3",method=RequestMethod.GET)
public ModelAndView get3(@RequestParam(value="p1",required=false)String p1,ModelMap map){
       map.addAttribute("p1", p1);//往页面传递
       return new ModelAndView("request/get2",map);
}

ModelAndView表示绑定了数据的视图,可以通过EL表达式去取值。
/**
 * 跳转到页面
 * @throws NoSuchAlgorithmException 
 */
@RequestMapping("userForm")
public String userForm(HttpServletResponse response) throws NoSuchAlgorithmException{
       CookieUtils.writeCookie(response, -1, "x", "dddddddddddddd");
       return "request/userForm";
}
/**
* 读取Cookie的值
* @param x
* @return
*/
@ResponseBody
@RequestMapping("cookie")
public String cookie(@CookieValue("x")String x){
       return x;
}

先访问http://localhost:8080/springmvc-param/request/userForm这个方法,跳转到一个页面,并向浏览器写入Cookie,第二个方法访问的时候即可通过@CookieValue方式来取到Cookie中的值。

绑定数据到一个对象上,支持get和post

一个User,一个Phone,一个User拥有多个Phone,为了演示,User中有一个List和Array的Phone的集合
public class User {
                
       private String userName;
       private String address;
       private List<Phone> phones;
       private Phone[] phones2;
       //省略GET和SET...
} 

public class Phone {
               private String brand;//手机品牌
}

Controller方法如下
/**
* 绑定数据到User对象,支持Map,Set,List,Array等,但是需要使用下标,不是很灵活
* 请查看user2的写法
* @param user
* @param map
*/
@RequestMapping(value="user")
public void user(User user,ModelMap map){
       map.addAttribute("user", user);
}

HTML表单如下
<form action="request/user" method="get" style="border:1px solid red;">
     <table>
           <tr><td colspan="2">这个表单演示了对象数据绑定的方法,以及对象中的Set,List,Array数据绑定(三者类似)</td></tr>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="userName" value="张三"></td>
            </tr>
            <tr>
                <td>用户地址:</td>
                <td><input type="text" name="address" value="江苏省无锡市新区菱湖大道200号"><br></td>
            </tr>
            <tr>
                <td>手机品牌:</td>
                <td>
                    <input type="text" name="phones[0].brand" value="SONY"><br>
                    <input type="text" name="phones[1].brand" value="MOTO"><br>
                    <input type="text" name="phones[2].brand" value="LG"><br>
                 </td>
             </tr>
             <tr>
                 <td>手机品牌2:</td>
                 <td>
                     <input type="text" name="phones2[0].brand" value="Apple"><br>
                     <input type="text" name="phones2[1].brand" value="Samsung"><br>
                     <input type="text" name="phones2[2].brand" value="HTC"><br>
                 </td>
              </tr>
              <tr>
                  <td colspan="2" style="text-align: right;">
                  <input type="submit" value="提交">
                  </td>
               </tr>
       </table>
</form>

一对多的时候,使用多一方的在一一方的对象中的属性名,加上数组下标,即phones[0].brand,phones[1].brand即可绑定到User的phones属性上,这种方法的局限性就是要求下标是正确的,否则会无法绑定,不是很方便,但是也有其适用场景。

下面这种方法就是比较方便了,仅支持post,但是必须要在消息转换器中配置JSON解析器
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>

并注册到RequestMappingHandlerAdapter的messageConverters中。

Controller如下:
/**
 * 这里可以接受List,Array,Set等,写法是一样的,注意前端写法<br>
 * 另外这个必须要使用MappingJacksonHttpMessageConverter这个消息转换器
 * 请看我上面的配置
 * @param user
 * @return
 */
 @ResponseBody
 @RequestMapping("user2")
 public String user2(@RequestBody List<User> user){
         System.out.println(user.size());
         return "";
 }

Javascript如下
var userList= new Array();
userList.push({userName:"xx",address:"fff"});
userList.push({userName:"zzzz",address:"ggggg"});
$.ajax({
  url:"request/user2",
  type:"post",
  data:JSON.stringify(userList),
  dataType:"json",
  contentType:"application/json",
  success:function(data){
   },error:function(data){
  }
});

该方法仅支持POST的方式,会使用到json2.js这个类库,注意设置contentType:"application/json"这个属性,否则会报415未知的类型异常。

传递简单的字符串数组,仅支持POST方式
/**
* 传递简单的字符串数组
* 这个方法只支持POST
* @param s
* @return
*/
@ResponseBody
@RequestMapping("array")
public String array(@RequestBody String[] s){
    System.out.println(s.length);
    return "";
 } 

var array=new Array();
array.push(1);
array.push(2);
array.push(3);
array.push(4);
array.push(5);
$.ajax({
    url:"request/array",
    type:"post",
    dataType:"json",
    data:JSON.stringify(array),
    dataType:"json",
    contentType:"application/json",
    success:function(data){
    },error:function(data){
    }
});

和上面的方法类似,注意contentType:"application/json",否则同样的415错误。

下面的方法是restful中的路径变量,支持get,post,delete等,如:xxx/1,xxx/2这种方式,经测试,这个方法的奇葩之处在于"xxx/5,4"以及"xxx/[5,4]"的效果是一样的,看代码:
/**
* 这个比较奇葩,来自一位朋友的写法,即.xxx/5,4这样的请求,SpringMVC竟然也是支持的
* @param id
* @return
*/
@ResponseBody
@RequestMapping(value="array/{id}",method=RequestMethod.GET)
public String array2(@PathVariable("id")Long[] id){
       System.out.println(id.length);
       return "array length:"+id.length+"";
}

可以直接将后面的路径变量,转换成相应的数组。可以在浏览器输入:http://localhost:8080/springmvc-param/request/array/5,4,3,2,1或者http://localhost:8080/springmvc-param/request/array/[5,4,3,2,1],都可以转换成数组。

如果一个表单对应多个实体类,恰好这些类中具有相同的属性,这时候SpringMVC就犯难了,我们要做的是让SpringMVC明白我们在给谁赋值。

支持post,get,put

如下,A,B,C,其中C中包含了A和B两个成员变量
public class A {
       private String x;
} 

public class B {
       private String x;
} 

public class C {
       private A a;
       private B b;
}

Controller如下
/**
* 一个表单对应多个Bean对象,这些Bean中有相同的属性,那么需要在分装他们的一个整体的对象
* 使之支持object.property的表达式
* @param c
*/
@ResponseBody
@RequestMapping("complex")
public void complexObject(C c){
       System.out.println(c.getA().getX());
       System.out.println(c.getB().getX());
}

HTML如下:
<form action="request/complex" method="POST" style="border:1px solid red;">
      <table>
             <tr>
                 <td>A对象:</td>
                 <td><input type="text" name="a.x" value="xxx"></td>
              </tr>
              <tr>
                  <td>B对象:</td>
                  <td><input type="text" name="b.x" value="yyy"><br></td>
              </tr>
              <tr>
                  <td colspan="2" style="text-align: right;">
                     <input type="submit" value="提交">
                  </td>
              </tr>
        </table>
</form>

通过object.property即可指定给谁赋值。


另外一个是关于Session取值的

代码如下
@Controller
@SessionAttributes(value="user")
@RequestMapping("/session")
public class SessionController {
 
    @RequestMapping(method=RequestMethod.GET)     
    public String setUser(ModelMap map){ 
        User user=new User(); 
        user.setAddress("xxx"); 
        user.setUserName("yyy");
        map.put("user", user);
        return "request/userForm";
    }
                
    @ResponseBody
    @RequestMapping(value="getUser",method=RequestMethod.GET)
    public String getUser(@ModelAttribute("user")User user){
           System.out.println(user.getUserName());
           return user.getUserName();
    }
 
}

在Controller上加上注解@SessionAttributes(value="user"),再使用ModelMap的put方法(非addAttribute方法),然后在getUser方法中,使用@ModelAttribute("user")即可取得session中的user对象


Maven依赖:
<properties>
            <springframework>4.0.5.RELEASE</springframework>
            <servlet>3.1.0</servlet>
            <jstl>1.2</jstl>
            <xstream>1.4.7</xstream>
            <commons-fileupload>1.3.1</commons-fileupload>
            <jackson>1.9.13</jackson>
</properties>
<dependencies>
            <!-- jackson json解析支持 -->
            <dependency>
                        <groupId>org.codehaus.jackson</groupId>
                        <artifactId>jackson-mapper-asl</artifactId>
                        <version>${jackson}</version>
            </dependency>
            <!-- Spring web mvc -->
            <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-webmvc</artifactId>
                        <version>${springframework}</version>
            </dependency>
            <!-- servlet -->
            <dependency>
                        <groupId>javax.servlet</groupId>
                        <artifactId>javax.servlet-api</artifactId>
                        <version>${servlet}</version>
            </dependency>
            <!-- JSTL -->
            <dependency>
                        <groupId>jstl</groupId>
                        <artifactId>jstl</artifactId>
                        <version>${jstl}</version>
            </dependency>
            <!--xml解析支持 -->
            <dependency>
                        <groupId>com.thoughtworks.xstream</groupId>
                        <artifactId>xstream</artifactId>
                        <version>${xstream}</version>
            </dependency>
</dependencies>

Spring配置
@EnableWebMvc// 启用SpringMVC
@ComponentScan(basePackages = "org.xdemo.example.springmvc")// 配置包扫描路径
@Configuration// 启用注解式配置
//继承WebMvcConfigurerAdapter可以是我们可以重写一些资源或者一些处理器
public class AppConfig extends WebMvcConfigurerAdapter {
 
               /**
                * 设置资源路径
                */
               @Override
               public void addResourceHandlers(ResourceHandlerRegistry registry) {
                      registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(31556926);
               }
 
               /**
                * 设置默认的Servlet请求处理器
                */
               @Override
               public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
                      configurer.enable();
               }
 
               /**
                * 设置视图解析器,以及页面路径
                * 
                * @return
                */
               @Bean
               public InternalResourceViewResolver getInternalResourceViewResolver() {
                               InternalResourceViewResolver resolver = new InternalResourceViewResolver();
                               resolver.setPrefix("/WEB-INF/views/");
                               resolver.setSuffix(".jsp");
                               return resolver;
               }
                
               /**
                * 配置消息转换器
                */
               @Override
               public void configureMessageConverters(
                      List<HttpMessageConverter<?>> converters) {converters.add(converter());
                                
               }
                
               /**
                * JSON格式的支持,这个很重要,只有加上这个JSON的消息转换器,才能够支持JSON格式数据的绑定
                * @return
                */
               @Bean
               public MappingJacksonHttpMessageConverter converter() {
                              MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
                               return converter;
               }
 
}
分享到:
评论

相关推荐

    springmvc 参数绑定例子1

    - **ModelAttribute**:当表单数据对应于一个复杂对象时,可以使用`@ModelAttribute`注解,Spring MVC会自动将请求参数映射到对象属性。 ```java @PostMapping("/saveUser") public String saveUser(@...

    springMVC前后交互代码,多对象传递

    在Spring MVC框架中,前后端交互是Web应用开发的核心部分,它涉及到控制器(Controller)、模型(Model)、视图(View)以及数据绑定等概念。本示例着重关注如何通过多种方式传递参数,包括单个参数、集合参数以及多...

    SpringMVC中使用@PathVariable绑定路由中的数组的方法

    在 SpringMVC 中,使用 @PathVariable 绑定路由中的数组是一种常见的需求,特别是在批量删除功能时,需要传递一个数组给后台,以便删除多条数据。在本文中,我们将详细介绍如何使用 @PathVariable 绑定路由中的数组...

    SpringMVC传递和返回对象实例以及zTree例子

    本示例将重点关注如何在控制器(Controller)中接收和返回对象实例,并结合zTree(一个流行的JavaScript树插件)展示数据。首先,我们需要了解SpringMVC的请求处理流程。 SpringMVC通过DispatcherServlet作为前端...

    SpringMVC:整合JQUERY与JSON

    - **数据序列化与反序列化**:SpringMVC使用`@RequestBody`和`@ResponseBody`注解将JSON数据自动转换为Java对象,反之亦然。 - **响应处理**:jQuery接收服务器返回的JSON数据,通过回调函数处理结果,更新页面...

    spring mvc 封装list到后台 SpringMVC_Multi_Row

    `@RequestParam`和`@PathVariable`等其他注解也可以用于数据绑定,但在这里,`@ModelAttribute`更适合处理复杂类型,如列表或自定义对象。 在实际应用中,前端的HTML表单需要以适当的格式(比如JSON数组或逗号分隔...

    qfedu三段springmvc

    对象数据绑定 id &lt;input type="text" name="id"&gt;&lt;br&gt; username &lt;input type="text" name="username"&gt;&lt;br&gt; score &lt;input type="text" name="score"&gt;&lt;br&gt; birthday &lt;input type="date" name="birthday"&gt;&lt;br&gt; ...

    基于springMVC3.2的REST源码,结合了jquery和json

    4. **数据绑定**:收到JSON响应后,jQuery可以方便地将数据绑定到DOM元素,如使用$.each()遍历JSON数组并动态创建HTML元素。 综上所述,这个项目提供了一个实用的示例,展示了如何在SpringMVC 3.2中构建RESTful服务...

    SpringMVC学习学习笔记

    1.3.3 数组和集合如List、Set等可以通过名称+`[]`来映射 1.3.4 日期类型的参数可以配合`@DateTimeFormat`进行格式化解析 1.3.5 RESTful风格的URL,利用HTTP动词(GET, POST, PUT, DELETE等)和资源路径,可以更清晰...

    springmvc_02 高级参数绑定 异常处理 文件上传

    - `Void`:通常用于需要使用`HttpServletRequest`和`HttpServletResponse`进行响应的情况,如重定向、响应JSON数据等。 - `String`:返回视图名,由视图解析器解析后返回具体的视图。 #### 四、异常处理 ##### ...

    Spring下的子框架SpringMVC实现多文件上传完整代码

    通过以上技术要点和实践示例的介绍,我们可以看到 SpringMVC 在处理多文件上传方面不仅提供了丰富的功能支持,而且通过合理的配置和使用,可以显著提高文件上传的效率和安全性。这对于构建高性能的 Web 应用程序来说...

    SpringMVC JSON数据交互及RESTful支持实现方法

    - jackson-databind-2.8.8.jar:JSON转换的数据绑定包,提供了将Java对象与JSON之间互相转换的能力。 为了在SpringMVC中更好地支持注解式开发,通常会配置springmvc-config.xml文件,以便自动注册...

    SpringMVC解析JSON请求数据问题解析

    在本文中,我们将深入探讨SpringMVC如何解析JSON请求数据,这对于开发RESTful API和服务至关重要。SpringMVC是Spring框架的一部分,专门用于处理Web请求,包括JSON格式的数据。在前后端分离的架构中,JSON成为了前后...

    Android上传图片到springmvc服务器全

    - 解析请求体:使用`@RequestBody`注解,Spring MVC会自动将请求体内容绑定到对应的Java对象。 - Base64解码:在服务器端,将接收到的Base64字符串解码回图片的字节数组。 - 文件存储:将字节数组写入到服务器的...

    在Hibernate+Spring+SpringMVC中集成JfreeChart

    6. **传递数据到视图**:在控制器(Controller层),将生成的图表字节数组和相关数据模型绑定到ModelAndView对象,然后重定向或转发到视图。 ```java ModelAndView modelAndView = new ModelAndView("chart"); ...

    springMVC框架下JQuery传递并解析Json数据

    首先,JSON的基本格式是以键值对的形式存储数据,支持数组、对象等数据结构。在JavaScript中,JSON数据可以轻松地被解析为JavaScript对象,反之亦然,这种特性让JSON在前端和后端的数据交换中变得非常高效和方便。 ...

    基于ssm框架与angular实现的增删改查业务

    它提供了完整的单页应用程序(SPA)解决方案,包括数据绑定、依赖注入、模块化和路由等功能。在实现增删改查业务时,Angular的双向数据绑定特性使得UI和模型数据保持同步,极大地提高了开发效率。 在描述中提到的...

    SSM集成应用

    - **数组类型绑定**:如String[]。 - **List类型绑定**:如List。 - **Map类型绑定**:如Map, String&gt;。 - **中文乱码问题**:解决客户端与服务器间字符集不一致导致的问题。 - **自定义参数绑定实现日期转换**...

    freemarket使用

    2. **数据模型** (Data Model): 数据模型是传递给模板的一组数据,它可以是简单的字符串或数字,也可以是复杂的对象图。 3. **配置** (Configuration): 配置对象负责管理模板的位置、加载方式、错误处理以及其他...

    spirngmvc js传递复杂json参数到controller的实例

    理解以上内容后,你可以灵活地处理JavaScript与Spring MVC Controller之间传递的复杂JSON数据,无论是简单的字符串列表还是自定义对象的集合。通过这种方式,可以方便地实现前后端的数据交互,提高应用程序的灵活性...

Global site tag (gtag.js) - Google Analytics