SpringMVC数据类型绑定总结

参考文章:(https://www.cnblogs.com/HD/p/4107674.html) 和
(https://blog.csdn.net/qq_33530388/article/details/72784199)

一、基本数据类型

Controller代码:

@RequestMapping("/addFruits")
public ModelAndView add(int id) {
    ModelAndView mav = new ModelAndView("showFruits");
        
    return mav;
}

表单代码:

<form action="addFruits" method="post">
        <table>
            <tr>
                <td>
                    编号:
                </td>
                <td>
                    <input name="id" value="10">
                </td>
            </tr>
        </table>
    </form>

注意:对于基本数据类型,表单提交的数据不能为 null 或 "",否则会出现数据转换的异常。所以,在开发过程中,对于可能为空的数据,最好将参数的数据类型定义为包装类型。

二、包装类型

Controller代码:

@RequestMapping("/addFruits")
public ModelAndView add(Integer id) {
    ModelAndView mav = new ModelAndView("showFruits");
        
    return mav;
}

表单代码:

<form action="addFruits" method="post">
    <table>
        <tr>
            <td>
                编号:
            </td>
                <td>
                <input name="id" value="10">
            </td>
        </tr>
    </table>
</form>

和基本数据类型基本一样,不同之处在于从表单传过来的数据可以为 "" 或null

三、自定义对象类型

Model代码:

public class Fruits {
    private String id;
    private Date createDate;
}

Controller代码:

@RequestMapping("/addFruits")
public ModelAndView add(Fruits fruitsObject) {
    ModelAndView mav = new ModelAndView("showFruits");
        
        //参数 fruitsObject 会默认被当做值加入到ModelAndView 中(),相当于:
    //mav.addObject("theFirstParam", fruitsObject);
    //其中,addObject 里第一个参数是根据 add() 的参数类型自动转成小驼峰命名,第二个参数是 add() 的参数名。
    //如果参数为基本数据类型或包装类型,则不会默认填充到ModelAndView 中。

    return mav;
}

表单代码:

<form action="addFruits" method="post">
    <table>
        <tr>
            <td>
                编号:
            </td>
            <td>
                <input name="id" value="10">
            </td>
        </tr>
                <tr>
            <td>
                请输入日期:
            </td>
            <td>
                <input type="date" name="createDate">
            </td>
        </tr> 
    </table>
</form>

按照上述的配置,就可以将表单中的数据封装到Control里了。但是运行上述代码时,会发现报错,报错的信息是:无法将 String 类型的 createDate 转换为 Date 类型的。

因此,对于表单中有日期类型的数据,需要我们自己定义转换器

自定义转换器主要有以下几种方式:
方式一:自定义日期转换器
自定义转换器代码:

package converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;

//需要实现Converter接口,这里是将String类型转换成Date类型
public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        // 实现 将日期串转成日期类型(格式是yyyy-MM-dd)
        SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");
        
        try {
            // 转换成功后直接返回
            return sm.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        
        //如果数据绑定失败,返回null
        return null;
    }
}

springmvc配置文件代码:

    <!--注解驱动,后续需要研究一下改驱动的实现原理-->
    <mvc:annotation-driven conversion-service="conversionService" />
    
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!-- converters转换器,converters为FormattingConversionServiceFactoryBean的属性之一 -->
        <property name="converters">
            <list>
                <!-- converters 的实现类DateConverter  -->
                <bean class="converter.DateConverter" />
            </list>
        </property>
    </bean>

方式二:引入jar包,调用其它类提供的日期转换器

待补充

四、自定义复合对象类型

Model代码:

public class Fruits {
    private String id;
    private Date createDate;
    //产品详细信息
    private FruitItem fruitItem;
}

//产品详细信息
public class FruitItem {
    private String id;
    private String name;
    private double price;
}

Controller代码:

@Controller
public class FruitsController {

    @RequestMapping("/addFruits")
    public ModelAndView add(Fruits fruitsObject) {
        ModelAndView mav = new ModelAndView("showFruits");
        
            //参数 fruitsObject 会默认被当做值加入到ModelAndView 中(),相当于:
        //mav.addObject("theFirstParam", fruitsObject);
        //其中,addObject 里第一个参数是根据 add() 的参数类型自动转成小驼峰命名,第二个参数是 add() 的参数名。
        //如果参数为基本数据类型或包装类型,则不会默认填充到ModelAndView 中。

        return mav;
    }
}

表单代码:

    <form action="addFruits" method="post">
        <table>
            <tr>
                <td>
                    请输入编号:
                </td>
                <td>
                    <input name="id" value="10">
                </td>
            </tr>
            <tr>
                <td>
                    请输入日期:
                </td>
                <td>
                    <input type="date" name="createDate">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品编号:
                </td>
                <td>
                    <input name="fruitItem.id" value="11">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItem.name" value="">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItem.price" value="">
                </td>
            </tr>
            
            <tr>
                <td>
                    <input type="submit" value="提交">
                </td>
            </tr>
        </table>
    </form>

Fruits 对象中有 fruitItem 属性,Control层代码保持不变,在表单中需要按照 "属性名(对象类型的属性).属性名" 来命名 input 的 name。

五、数组绑定

数组的绑定指的是前台传来多个同一类型的数据,我们在controller中使用数组形参来接收前台传来的数据。在controller中,我们需要将这些id号全部获取并放到一个数组中。
Controller代码:

@Controller
public class FruitsController {

    @RequestMapping("/addFruits")
    public ModelAndView add(String[] id) {
        ModelAndView mav = new ModelAndView("showFruits");
        
        for(String str : id){
            System.out.println(str);
        }
        
        return mav;
    }
}

表单代码:

    <form action="addFruits" method="post">
        <table>
            <tr>
                <td>
                    请勾选编号:
                </td>
                <td>
                    <input type="checkbox" name="id" value="1">
                    <input type="checkbox" name="id" value="2">
                    <input type="checkbox" name="id" value="3">
                </td>
            </tr>

            <tr>
                <td>
                    <input type="submit" value="提交">
                </td>
            </tr>
        </table>
    </form>

注意:Contrlller 方法中的参数 名称(id) 与表单中 input中的 name(id) 保持一致。

六、List绑定

List 需要绑定在对象上,不能直接写在 control 方法的参数中
Model代码:

//产品详细信息
public class FruitItem {
    private String name;
    private double price;
}

public class Fruits {
    private String id;
    //产品详细信息List
    private List<FruitItem> fruitItemList;
}

Controller代码:

    @RequestMapping("/addFruits")
    public ModelAndView add(Fruits fruitsObject) {
        ModelAndView mav = new ModelAndView("showFruits");
        
            //参数 fruitsObject 会默认被当做值加入到ModelAndView 中(),相当于:
        //mav.addObject("theFirstParam", fruitsObject);
        //其中,addObject 里第一个参数是根据 add() 的参数类型自动转成小驼峰命名,第二个参数是 add() 的参数名。
        //如果参数为基本数据类型或包装类型,则不会默认填充到ModelAndView 中。

        return mav;
    }

表单代码:

    <form action="addFruits" method="post">
        <table>
            <tr>
                <td>
                    请输入编号:
                </td>
                <td>
                    <input name="id" value="10">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItemList[0].name" value="">
                </td>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItemList[0].price" value="">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItemList[1].name" value="">
                </td>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItemList[1].price" value="">
                </td>
            </tr>
            
            <tr>
                <td>
                    <input type="submit" value="提交">
                </td>
            </tr>
        </table>
    </form>

值得一提的是,Spring会创建一个以最大下标值为size的List对象,所以,如果表单中有动态添加行、删除行的情况,就需要特别注意,譬如一个表格,用户在使用过程中经过多次删除行、增加行的操作之后,下标值就会与实际大小不一致,这时候,List中的对象,只有在表单中对应有下标的那些才会有值,否则会为null。

七、Set绑定:

Set和List类似,也需要绑定在对象上,而不能直接写在Controller方法的参数中。但是,绑定Set数据时,必须先在Set对象中add相应的数量的模型对象。
Model代码:

//产品详细信息
public class FruitItem {
    private String name;
    private double price;
}

public class Fruits {
    private String id;
    private Date createDate;
    
    //产品详细信息List
    private Set<FruitItem> fruitItemSet = new HashSet<FruitItem>();
    
    public Fruits(){
        fruitItemSet.add(new FruitItem());
        fruitItemSet.add(new FruitItem());
        fruitItemSet.add(new FruitItem());
    }
}

Controller代码:

@Controller
public class FruitsController {

    @RequestMapping("/addFruits")
    public ModelAndView add(Fruits fruitsObject) {
        ModelAndView mav = new ModelAndView("showFruits");
        
        for(FruitItem fruitItem : fruitsObject.getFruitItemSet()){
            System.out.println(fruitItem.getName() + " -- " + fruitItem.getPrice());
        }
        
            //参数 fruitsObject 会默认被当做值加入到ModelAndView 中(),相当于:
        //mav.addObject("theFirstParam", fruitsObject);
        //其中,addObject 里第一个参数是根据 add() 的参数类型自动转成小驼峰命名,第二个参数是 add() 的参数名。
        //如果参数为基本数据类型或包装类型,则不会默认填充到ModelAndView 中。

        return mav;
    }
}

表单代码:

    <form action="addFruits" method="post">
        <table>
            <tr>
                <td>
                    请输入编号:
                </td>
                <td>
                    <input name="id" value="10">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItemSet[0].name" value="">
                </td>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItemSet[0].price" value="">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItemSet[1].name" value="">
                </td>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItemSet[1].price" value="">
                </td>
            </tr>
            
            <tr>
                <td>
                    <input type="submit" value="提交">
                </td>
            </tr>
        </table>
    </form>

基本和List绑定类似。
需要特别提醒的是,如果最大下标值大于Set的size,则会抛出org.springframework.beans.InvalidPropertyException异常。所以,在使用时需要先有些不便。

八、Map绑定:

Model代码:
Map最为灵活,它也需要绑定在对象上,而不能直接写在Controller方法的参数中。

//产品详细信息
public class FruitItem {
    private String name;
    private double price;
}

public class Fruits {
    private String id;
    
    //产品详细信息List
    private Map<String, FruitItem> fruitItemMap = new HashMap<String, FruitItem>();
}

Controller代码:

@Controller
public class FruitsController {

    @RequestMapping("/addFruits")
    public ModelAndView add(Fruits fruitsObject) {
        ModelAndView mav = new ModelAndView("showFruits");
        
        for(Entry<String, FruitItem> fruitItemMap : fruitsObject.getFruitItemMap().entrySet()){
            System.out.println(fruitItemMap.getKey() + " -- " + fruitItemMap.getValue().getName() + " -- " + fruitItemMap.getValue().getPrice());
        }
        
            //参数 fruitsObject 会默认被当做值加入到ModelAndView 中(),相当于:
        //mav.addObject("theFirstParam", fruitsObject);
        //其中,addObject 里第一个参数是根据 add() 的参数类型自动转成小驼峰命名,第二个参数是 add() 的参数名。
        //如果参数为基本数据类型或包装类型,则不会默认填充到ModelAndView 中。

        return mav;
    }
}

表单代码:

    <form action="addFruits" method="post">
        <table>
            <tr>
                <td>
                    请输入编号:
                </td>
                <td>
                    <input name="id" value="10">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItemMap[x].name" value="">
                </td>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItemMap[x].price" value="">
                </td>
            </tr>
            <tr>
                <td>
                    请输入产品名称:
                </td>
                <td>
                    <input name="fruitItemMap[y].name" value="">
                </td>
                <td>
                    请输入产品价格:
                </td>
                <td>
                    <input name="fruitItemMap[y].price" value="">
                </td>
            </tr>
            
            <tr>
                <td>
                    <input type="submit" value="提交">
                </td>
            </tr>
        </table>
    </form>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容