SpringMVC|参数绑定


1. 什么是SpringMVC参数绑定

就是将URL中的的请求参数,进行类型转换(String或其他类型),将转换后的值在赋值给Controller方法形参中,然后Controller就可以直接使用该形参。

2. 默认的参数绑定类型

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • Model:数据模型,主要存储要返回到客户端的数据的。功能类似于Request对象。
  • ModelMap
  • 演示
@RequestMapping("/Parameter")
    public Stirng parameter(HttpServletRequest request,HttpServletResponse response,
                            HttpSession session,Model model,ModelMap modelMap) throws Exception{
        request.setAttribute("requestParameter", "request类型");
        response.getWriter().write("response");
        session.setAttribute("sessionParameter", "session类型");
        model.addAttribute("modelParameter", "model类型");
        modelMap.addAttribute("modelMapParameter", "modelMap类型");
         
        return "success";
    }

3. 简单类型

  • 请求URL
http://localhost:8080/springmvc/test/queryById?id=1&name=zhangsan

参数为id=1&name=zhangsan

  • Controller
    注意:请求参数的key,需要和controller方法形参名称一致,注意类型是否匹配。
@RequestMapping(“queryById”)
public String queryItemById(int id,String name){}
  • RequestParam
  • 作用:
    1. 相当于request.getParameter(请求参数中的key);
    2. 将获取的值,绑定到该注解修饰中的参数中;
  • 属性:
    • value:URL请求参数中的key;
    • required:true/false,表示该URL是否必须要带有该参数,默认是true;
    • default:如果required设置为true,但是URL中没有指定的key,则默认取该值进行参数绑定。

4. POJO类型

  • 请求参数
id=10&name=zhangsan
  • Controller
    使用要求
    1. 使用一个POJO类型的参数作为Contoller方法的参数形参,进行形参绑定。
    2. 请求参数的key,需要和一个POJO类型的属性名称一致。
    3. 如果参数的key出现这种方式address.provinceName,需要需要POJO类型中嵌套POJO类型的属性进行接受请求参数User#Address(address)#provinceName

代码

@RequestMapping("saveUser")
    public String saveUser(User user,Model model) {
        model.addAttribute("msg", "接收到的参数:"+user.toString());
        return "success";
    }
public class User {
    private int id;
    private String username;
    private Date birthday;
    private String sex;

    // 演示包装POJO参数绑定
    private Address address;
}

5. 日期类型

  • 问题
    对于字符串类型的日期参数,转换成Data的参数,会有转换类型问题。原因是因为,SpringMVC无法确定页面传入的日期格式是什么类型的,所以无法进行无法参数转换。
  • 解决办法
    Converter:实现类型转换
public class DateConverter implements Converter<String,Date>{

    @Override
    public Date convert(String source) {
        // 使用Java中 SimpleDateFormat API完成日期转换
        String pattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern );
        try {
            return dateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

将Converter注册到处理器适配器中

<!-- 配置注解方式处理器对应的适配器和映射器,同时还注入了很多其他的bean -->
    <mvc:annotation-driven
        conversion-service="conversionService" />

    <!-- 配置ConversionService -->
    <bean id="conversionService"
        class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.springmvc.controller.converter.DateConverter"></bean>
            </set>
        </property>
    </bean>

6. 集合或者类型

6.1 元素是简单类型的集合或数组

  • 注意
    1. 直接使用LIst集合或者数组作为形参,List集合会报错。
    2. 直接使用POJO类型作为形参,并且该POJOlei类型拥有一个List集合属性或者数组属性。这种情况下List和数组都可以成功接收参数。
    3. 请求参数key和形参名称或者属性名称要一致。
  • 请求参数
id=1&id=2&id=3
  • Controller方法
    第一个和第三个是成功的,第二个不成功。
    @RequestMapping("findUserByIds")
    public String findUserByIds(Integer[] id,Model model) {
        model.addAttribute("msg", "接收到的参数:"+id);
        return "success";
    }
    @RequestMapping("findUserByIds2")
    public String findUserByIds2(List<Integer> id,Model model) {
        model.addAttribute("msg", "接收到的参数:"+id);
        return "success";
    }
    @RequestMapping("findUserByIds3")
    public String findUserByIds3(User user,Model model) {
        model.addAttribute("msg", "接收到的参数:"+user.getUid());
        return "success";
    }
public class User {

    // 演示批量简单类型参数接收
    private List<Integer> uid = new ArrayList<>();
}

6.2 元素是POJO的类型或数组

  • 注意
    1. 直接使用List集合或者数组作为形参,都会报错。
    2. 必须使用POJO类型作为形参,并且该POJO类型拥有一个List集合属性或者数组属性。这种情况下List和数组都可以成功接收参数。
    3. 请求参数key和属性名称要一致。
  • 请求参数
    POST请求
<!-- 将request请求参数,绑定到[元素是POJO类型的List集合或Map集合]参数 -->
    <form action="${pageContext.request.contextPath}/user/updateUser" method="post">
        <!-- itemList[集合下标]:集合下标必须从0开始 -->
        <!-- 辅助理解:先将name属性封装到一个Item对象中,再将该Item对象放入itemList集合的指定下标处 -->
        购买商品1名称:<input type="text" name="itemList[0].name"><br />
        购买商品1价格:<input type="text" name="itemList[0].price"><br />
        购买商品2名称:<input type="text" name="itemList[1].name"><br />
        购买商品2价格:<input type="text" name="itemList[1].price"><br />

        <input type="submit" value="保存">
    </form>

GET请求

itemList[0].id=1&itemList[0].name=zhangsan&itemList[0].price=100&itemList[1].id=2&itemList[1].name=lisi&itemList[1].price=200
  • Controller方法
@RequestMapping("updateUser")
    public String updateUser(User user,Model model) {
        model.addAttribute("msg", "接收到的参数:"+user.getUid());
        return "success";
    }
public class User {
    
    // 将request请求参数,绑定到[元素是POJO类型的List集合]参数 
    private List<Item> itemList = new ArrayList<>();

}

6.3 Map集合

  • 注意
    1. 需要使用POJO类型来接受,POJO类型中有一个Map类型的参数。
    2. Map类型的属性和名称,要求和请求参数[]前面的名称一致。
    3. Map的key要唯一,value要求是一个POJO类型。
  • 请求参数
itemMap['item1'].name=zhangsan&itemMap['item1'].price=100&itemMap['item2'].name=lisi&itemMap['item2'].price=200
  • POJO
public class User {

    // 将request请求参数,绑定到[元素是POJO类型的Map集合]参数 
    private Map<String, Item> itemMap = new HashMap<>();
}
public class Item {
    private Integer id;

    private String name;

    private Float price;

    private String pic;

    private Date createtime;

}

7. 文件类型

  • 注意
    JSP
form表单需要设置enctype=multipart/form-data

第三方依赖

commons-fileupload
commons-io

SpirngMVC的支持

MultipartResolver:解析文件类型的参数,绑定到MultipartFile类型的参数中,需要在springmvc.xml配置
MultipartFile:通过该参数,可以获取文件数据,包括文件名称和文件内容。
  • 代码配置
    JSP
<!-- 文件类型参数绑定 -->
    <form action="${pageContext.request.contextPath}/fileupload" method="post" enctype="multipart/form-data">
        图片:<input type="file" name="uploadFile" /><br /> 
        <input type="submit" value="上传" />
    </form>

springmvc.xml

<!-- 配置多部件解析器 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 限制上传文件的大小,最大可以上传多大,单位是字节 -->
        <property name="maxUploadSize" value="5000000"></property>
    </bean>

Controller

@RequestMapping("fileupload")
    public String findUserById(MultipartFile uploadFile,Model model) throws Exception {
        //编写文件上传逻辑(mvc模式和三层结构模式)
        //三层模式:表现层(controller、action)、业务层(service、biz)、持久层(dao、mapper)
        //MVC模式主要就是来解决表现层的问题的(原始的表现层是使用Servlet编写,即编写业务逻辑,又编写视图展示)
        
        if(uploadFile != null){
            System.out.println(uploadFile.getOriginalFilename());
            //原始图片名称
            String originalFilename = uploadFile.getOriginalFilename();
            //如果没有图片名称,则上传不成功
            if(originalFilename != null && originalFilename.length()>0)
            {
                //存放图片的物理路径
                String picPath = "E:\\";
                //获取上传文件的扩展名
                String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
                //新文件的名称
                String newFileName = UUID.randomUUID()+extName;
                //新的文件
                File newFile = new File(picPath+newFileName);
                //把上传的文件保存成一个新的文件
                uploadFile.transferTo(newFile);
                //同时需要把新的文件名更新到数据库中
            }
        }

        
        model.addAttribute("msg", "文件上传成功");
        return "success";
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容