zoukankan      html  css  js  c++  java
  • SpringMVC的参数绑定

    一、@RequestMapping注解说明

      通过@RequestMapping注解可以定义不同的处理器映射规则。
    URL路径映射
    @RequestMapping(value="/item")或@RequestMapping("/item")
    value的值是数组,可以将多个url映射到同一个方法

      窄化请求映射
    在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。

    如下:
    @RequestMapping放在类名上边,设置请求前缀
    @Controller
    @RequestMapping("/item")

    方法名上边设置请求映射url:
    @RequestMapping放在方法名上边,如下:
    @RequestMapping("/queryItem ")

    访问地址为:/item/queryItem

      请求方法限定
    限定GET方法
    @RequestMapping(method = RequestMethod.GET)

    如果通过Post访问则报错:
    HTTP Status 405 - Request method 'POST' not supported

    例如:
    @RequestMapping(value="/editItem",method=RequestMethod.GET)
    限定POST方法
    @RequestMapping(method = RequestMethod.POST)
    如果通过Post访问则报错:
    HTTP Status 405 - Request method 'GET' not supported

    GET和POST都可以
    @RequestMapping(method={RequestMethod.GET,RequestMethod.POST})

    二、Controller的返回值类型

    1.返回ModelAndView

      controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。

    2.返回void
      在controller方法形参上可以定义request和response,使用request或response指定响应结果:
      (1)、使用request转向页面,如下:
    request.getRequestDispatcher("页面路径").forward(request, response);
      (2)、也可以通过response页面重定向:
    response.sendRedirect("url")
      (3)、也可以通过response指定响应结果,例如响应json数据如下:
    response.setCharacterEncoding("utf-8");
    response.setContentType("application/json;charset=utf-8");
    response.getWriter().write("json串");

    3.返回字符串(逻辑视图名)

      controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。
    //指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/jsp/item/editItem.jsp
    return "item/editItem";

      Redirect重定向。
    Contrller方法返回结果重定向到一个url地址,如下商品修改提交后重定向到商品查询方法,参数无法带到商品查询方法中。

    //重定向到queryItem.action地址,request无法带过去
    return "redirect:queryItem.action";
    

      redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,因为转发即执行了一个新的request和response。
    由于新发起一个request原来的参数在转发时就不能传递到下一个url,如果要传参数可以/item/queryItem.action后边加参数,如下:
    /item/queryItem?...&…..
      forward转发
    controller方法执行后继续执行另一个controller方法,如下商品修改提交后转向到商品修改页面,修改商品的id参数可以带到商品修改方法中。

    //结果转发到editItem.action,request可以带过去
    return "forward:editItem.action";
    

      forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和response。所以转发前请求的参数在转发后仍然可以读取到。

    三、参数绑定

    1、参数的绑定过程

      客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上.

    2、默认支持的类型

      (1)HttpServletRequest。
      在controller中可以通过HttpServletRequest对象来获取请求信息。
      (2)HttpServletResponse。
      ;在controller中可以通过HttpServletResponse对象来处理响应信息。
      (3)HttpSession。
      ;在controller中可以通过HttpSession对象来得到session对象中存放的对象。
      (4)Model/ModelMap。
      ;Model是一个接口,ModelMap是一个接口实现,在controller中可以通过Model/ModelMap对象来将数据填充到request域当中。

    3.简单类型的参数绑定

      此处只介绍Integet类型,其他简单类型相同
      第一种情况:request传入的参数名和Controller中的形参的名称一致,这样便可以直接绑定成功。
    示例:
    jsp页面的请求

     <td><a href="${pageContext.request.contextPath}/queryItemById.action?id=${items.id}">修改</a> </td>
    

    controller中接受改参数:

     @RequestMapping("/queryItemById")
        public ModelAndView queryItemById(Integer id) throws Exception{
    
           ItemsExtend itemsExtend = itemsService.queryItesmById(id);
           ModelAndView modelAndView = new ModelAndView();
           modelAndView.addObject("itemsExtend",itemsExtend);
           modelAndView.setViewName("updateitem");
           return modelAndView;
        }
    

      第二种情况:request传入的参数名和Controller中的形参名称不一致。这种情况下要绑定成功,则必须要使用@RequestParam注解。示例:
    jsp请求页面:

     <td><a href="${pageContext.request.contextPath}/queryItemById.action?id=${items.id}">修改</a> </td>
    

    Controller中接受参数:

       @RequestMapping("/queryItemById")
        /**
         * 1、通过@RequestParam注解进行参数绑定,在要绑定的参数前面加@RequestParam即可。
         * 2、value的值是请求中传过来的参数的名称。
         * 3、通过required可以指定改参数是否必传,设置为true必传,不传会报错
         */
        public ModelAndView queryItemById(@RequestParam(value = "id",required = true) Integer item_id) throws Exception{
    
           ItemsExtend itemsExtend = itemsService.queryItesmById(item_id);
           ModelAndView modelAndView = new ModelAndView();
           modelAndView.addObject("itemsExtend",itemsExtend);
           modelAndView.setViewName("updateitem");
           return modelAndView;
        }
    

    4.pojo类型的参数绑定

      只要页面中input的name属性值和controller中的pojo形参中的属性名称一致,就可以将页面中的数据绑定到pojo当中。下面以商品修改为例进行说明:
      pojo类:pojo类中的属性名称和数据库中表的列名保持一致。

    public class Items {
        private Integer id;
    
        private String name;
    
        private Float price;
    
        private String pic;
    
        private Date createtime;
    
        private String detail;
       // getter and setter
    }
    

      controller方法中使用Items类的扩展类来作为形参,该类继承了Items类。

       @RequestMapping("/updateitems")
        public String updateitems(Integer id,ItemsExtend itemsExtend) throws Exception{
            itemsService.updateitems(id,itemsExtend);
            return "redirect:queryItems.action";
        }
    

      jsp页面中input框的name属性值必须要和Items中的属性值名称保持一致,这样才能成功进行绑定。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
             pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        <head>
             <title>修改商品信息</title>
        </head>
        <body>
            <form action="${pageContext.request.contextPath}/updateitems.action" method="post">
                <input type="hidden" name="id" value="${itemsExtend.id}">
                <table width="100%" border= 1>
    
                    <tr>
                        <td> 商品名称:</td>
                       <td><input type="text" name="name" value="${itemsExtend.name}"></td>
                    </tr>
                    <tr>
                        <td> 商品价格:</td>
                       <td><input type="text" name="price" value="${itemsExtend.price}"></td>
                    </tr>
                 <%--   <tr>
                        <td>商品图片:</td>
                        <td>
                            <img src="${itemsExtend.pic}" alt="图片">
                            <br/>
                            <input type="file" name="pic">
                        </td>
                    </tr>--%>
                    <tr>
                        <td> 商品日期:</td>
                       <td><input type="text" name="createtime" value="<fmt:formatDate value="${itemsExtend.createtime}" pattern="yyyy-MM-dd HH:mm:s"/>"></td>
                    </tr>
                    <tr>
                        <td>商品描述:</td>
                        <td><textarea rows="6"  name="detail">${itemsExtend.detail}</textarea></td>
                    </tr>
                </table>
                <input type="submit" value="提交">
            </form>
        </body>
    </html>
    

    5.POST请求中的中文乱码问题

      在POST请求中如果有中文会出现乱码,解决方法为在 web.xml文件中加入一个过滤器即可。

       <!--解决POST提交中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    6、自定义类型转换器

      在前面的案例中,更新商品信息时使用到了日期时间,但是我们在pojo中定义的日期类型为java.util.Date类型,这样会造成时间的丢失。示例:
    更新Items信息数据:

    跟新后的商品信息:

    解决办法:
      自定义日期类型的绑定组件,然后将其注入到处理器适配器中即可。
    自定义的日期类型绑定。要自定义一个类型绑定必须要实现Converter<T,S>接口,然后实现convert()方法即可。
    自定义的日期类型绑定:

    /**
     * 自定义日期参数绑定
     * 1、必须要实现Converter<T,S>接口。
     * 2、Converter接口中的第一个参数为源类型,第二个参数为目标类型
     * 3、在convert方法里面处理类型转换。
     */
    public class ItemDateConvert implements Converter<String,Date> {
        @Override
        public Date convert(String s) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                return simpleDateFormat.parse(s);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    在springmvc的配置文件中,在处理器适配器中注入该自定义的额参数绑定器。
     第一种注入方式:

    <!--注解适配器 -->
    	<bean
    		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    		 <property name="webBindingInitializer" ref="customBinder"></property> 
    	</bean>
    	
    	<!-- 自定义webBinder -->
    	<bean id="customBinder"
    		class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
    		<property name="conversionService" ref="conversionService" />
    	</bean>
    	<!-- conversionService -->
    	<bean id="conversionService"
    		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    		<!-- 转换器 -->
    		<property name="converters">
    			<list>
    				<bean class="com.jack.Convert.ItemDateConvert"/>
    			</list>
    		</property>
    	</bean>
    

     第二种注入方式:

      <!--自定义参数绑定-->
        <bean id="conersionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <!--转换器-->
            <property name="converters">
                <list>
                    <!--日期转换器-->
                   <bean class="com.jack.Convert.ItemDateConvert"/>
                </list>
            </property>
        </bean>
        <!--注入自定义参数绑定器-->
        <mvc:annotation-driven conversion-service="conersionService"></mvc:annotation-driven>
    

    7.pringmvc和struts2的区别

    (1)springmvc基于方法开发的,struts2基于类开发的。

    (2)springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。
    方法执行结束,形参数据销毁。
    springmvc的controller开发类似service开发。

    (3)springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。

    (4)经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。

    8、数组的绑定

     对商品进行批量删除,在list页面中每一条记录添加多选框,进行多选后将所选商品的id以数组的方式传到controller方法中,在controller方法中使用数组形式的形参来进行接受。示例:
    jsp页面:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
             pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        <head>
             <title>商品展示</title>
            <script type="application/javascript">
    
    
                function deletes() {
                    document.itemform.action = "${pageContext.request.contextPath}/deleteItems.action"
                    document.itemform.submit();
                }
                   function query() {
                       document.itemform.action = "${pageContext.request.contextPath}/queryItems.action"
                       document.itemform.submit();
                   }
            </script>
        </head>
        <body>
            <form id="itemform" name="itemform" action="" >
                <table width="100%" border= 1>
                    <tr>
                        <td><input type="submit" value="查询" onclick="query()"></td>
                        <td><input type="button" id="delete" value="批量删除" onclick="deletes()"></td>
                    </tr>
                    <tr>
                        <td>选择</td>
                        <td>商品id</td>
                        <td>商品名称</td>
                        <td>商品价格</td>
                      <%--  <td>商品图片</td>--%>
                        <td>商品日期</td>
                        <td>商品描述</td>
                        <td>操作</td>
                    </tr>
                    <c:forEach items="${itemsExtendList}" var="items">
                   <tr>
                        <td><input type="checkbox" name="ids" id="ids" value="${items.id}"></td>
                        <td>${items.id}</td>
                        <td>${items.name}</td>
                        <td>${items.price}</td>
                      <%-- <td><img src="${items.pic}" alt="图片"></td>--%>
                       <td><fmt:formatDate value="${items.createtime}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate></td>
                       <td>${items.detail}</td>
                       <td><a href="${pageContext.request.contextPath}/queryItemById.action?id=${items.id}">修改</a> </td>
                   </tr>
                    </c:forEach>
                </table>
            </form>
        </body>
    </html>
    

    controller方法:

    @RequestMapping("/deleteItems")
        public String deleteItems(String[] ids,ItemsCustom itemsExtend) throws Exception{
    
            for (int i =0 ;i<ids.length ;i++){
                System.out.println(ids[i]);
            }
          //  itemsService.deleteItems(ids,itemsExtend);
            return "redirect:queryItems.action";
        }
    

    9、list的参数绑定

     批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中。
    jsp页面:

       <c:forEach items="${itemsExtendList}" var="items" varStatus="statu">
                   <tr>
                        <td><input type="text" name="itemsCustomList[${statu.index}].id" value="${items.id}"></td>
                        <td><input type="text" name="itemsCustomList[${statu.index}].name" value="${items.name}"></td>
                        <td><input type="text" name="itemsCustomList[${statu.index}].price" value="${items.price}"></td>
                       <td><input type="text" name="itemsCustomList[${statu.index}].createtime" value="<fmt:formatDate value="${items.createtime}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>"></td>
                       <td><input type="text" name="itemsCustomList[${statu.index}].detail" value="${items.detail}"></td>
                   </tr>
                    </c:forEach>
    

    controller方法 :

    @RequestMapping("/updateAllSelectItems")
        public String updateAllSelectItems(ItemsVo itemsVo) throws Exception{
          /*  List<ItemsCustom> itemsExtendList =itemsService.queryItesm();*/
           List<ItemsCustom> list = itemsVo.getItemsCustomList();
            for (ItemsCustom item: list) {
                System.out.println(item);
            }
           /* ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("itemsExtendList",itemsExtendList);
            modelAndView.setViewName("itemlist");*/
            return "redirect:queryItems.action";
        }
    

    pojo:

    public class ItemsVo {
        List<ItemsCustom> itemsCustomList ;
    
        public List<ItemsCustom> getItemsCustomList() {
            return itemsCustomList;
        }
    
        public void setItemsCustomList(List<ItemsCustom> itemsCustomList) {
            this.itemsCustomList = itemsCustomList;
        }
    }
    

    10.map数据的绑定

    controll方法 :

    @RequestMapping("/updateAllSelectItemsMap")
    public String updateAllSelectItemsMap(ItemsVo itemsVo) throws Exception{
    
        System.out.println(itemsVo.getItemsMap());
      
        return "redirect:queryItems.action";
    }
    

    jsp页面:

      <c:forEach items="${itemsExtendList}" var="items" varStatus="statu">
                   <tr>
                        <td><input type="text" name="itemsMap['id']" value="${items.id}"></td>
                        <td><input type="text" name="itemsMap['name']" value="${items.name}"></td>
                        <td><input type="text" name="itemsMap['price']" value="${items.price}"></td>
                       <td><input type="text" name="itemsMap['createtime']" value="<fmt:formatDate value="${items.createtime}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>"></td>
                       <td><input type="text" name="itemsMap['detail']" value="${items.detail}"></td>
                   </tr>
                    </c:forEach>
    

    pojo类:

    public class ItemsVo {
    
        Map<String,Object> itemsMap = new HashMap<>();
    
        public Map<String, Object> getItemsMap() {
            return itemsMap;
        }
    
        public void setItemsMap(Map<String, Object> itemsMap) {
            this.itemsMap = itemsMap;
        }
    }
  • 相关阅读:
    RESTFUL 设计风格
    GET与POST的区别
    pycharm 对数据库进行可视化操作
    ORM 的基本操作
    pycharm 直接删掉数据表之后,makemigration和migrate 之后,数据库中依然没有生成数据表的问题
    DOM
    BOM对象
    JavaScript
    traversal child window of parent window
    tkinter threading unblock GUI ( check if the thread exists)
  • 原文地址:https://www.cnblogs.com/jack1995/p/7357562.html
Copyright © 2011-2022 走看看