SpringMVC--请求参数绑定

SpringMVC目录:

页面与控制器交换数据的方式:

  • Spring MVC页面传值到控制器
    (1)使用Request进行页面传值到控制器(不建议使用)
    (2)使用属性进行页面传值到控制器
    (3)使用Bean对象进行页面传值到控制器

  • Spring MVC控制器传值到页面
    (1)使用Request、Session进行控制器传值到页面(不建议使用)
    (2)使用ModelAndView进行控制器传值到页面
    (3)使用ModelMap进行控制器传值到页面(建议使用)

请求参数是通过表单/URL?加上后面的参数(key=value)组成的,例如:xxxx:8080?username=aaa&password=111中的username和password就是请求参数。

SpringMVC绑定请求参数:
(1)请求地址提供请求参数:username、password。
(2)控制器中的方法进行参数接收:指定和请求参数同样的名称
(3)当请求参数名和控制器指定名称不一致时将无法取得参数
(4)可以在控制器的参数中通过@ReqeustParam指定URL传递参数名称

/**
 * @Author: Ly
 * @Date: 2020-09-22 17:14
 */
@Controller
@RequestMapping("/param")
public class ParamController {

    /**
     * 请求参数
     * @return
     */
    @RequestMapping("/testParam")
    public String testParam(String username,String password){
        System.out.println("执行了...");
        System.out.println("用户名是:"+username);
        System.out.println("密码是:"+password);
        return "success";
    }
  
}

传送不同类型的的数据:

  • 基本类型参数:包括基本类型和 String 类型
@RequestMapping("/testParam")
public String testParam(String username,String password){
    System.out.println("执行了...");
    System.out.println("用户名是:"+username);
    System.out.println("密码是:"+password);
    return "success";
}
  • POJO 类型参数:实体类
    在jsp页面中添加一个表单,并创建对应的实体类Account(name与参数名称一致)
<form action="param/saveAccount" method="post">
    姓名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    金额:<input type="text" name="money"><br/>
    <input type="submit" value="提交">
</form>
  • 请求参数绑定,把数据封装到Javabean的类中
/**
 * @return
 */
@RequestMapping("/saveAccount")
public String saveAccount(Account account){
    System.out.println("执行了...");
    System.out.println(account);
    return "success";
}
  • POJO 类型参数:实体类+关联实体类
    在jsp页面中添加一个表单,新建一个User类,属性包括name和age,并在Account类中添加User类对象
<form action="param/saveAccount" method="post">
    姓名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    金额:<input type="text" name="money"><br/>
    用户姓名:<input type="text" name="user.name"><br/>
    用户年龄:<input type="text" name="user.age"><br/>
    <input type="submit" value="提交">
</form>
  • 数组和集合类型参数:包括 List 结构和 Map 结构的集合(包括数组)
    在jsp页面中添加一个表单,删除Account类中User对象属性,并定义一个List<User> list;集合对象属性和一个Map<String,User> map;集合对象属性。
<%--把数据封装Account类中,类中存在list和map集合--%>
<form action="param/saveAccount" method="post">
    姓名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    金额:<input type="text" name="money"><br/>

    用户姓名:<input type="text" name="list[0].name"><br/>
    用户年龄:<input type="text" name="list[0].age"><br/>
    用户姓名:<input type="text" name="map['one'].name"><br/>
    用户年龄:<input type="text" name="map['one'].age"><br/>

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

SpringMVC 绑定请求参数是自动实现的,但是必须按照相关格式,如果绑定基本类型或者 String 类型,要求我们的参数名称必须和控制器中方法的形参名称保持一致(严格区分大小写)。如果是 POJO 类型,或者它的关联对象:要求表单中参数名称和 POJO 类的属性名称保持一致,并且控制器方法的参数类型是 POJO 类型。如果是集合类型,可以将集合类型的请求参数放在 POJO 中,在表单中请求参数名称要和 POJO 中集合属性名称相同,还可以接收的请求参数是 json 格式数据,并通过相关注解实现。

如果遇特殊类型转换要求,需要我们自己编写自定义类型转换器

案例:日期类类型的数据
日期的格式为2020/10/10,如果我们把格式修改为2020-10-10,SpringMVC在绑定参数时就会报错。

定义日期类

public class DataType implements Serializable{

    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "date=" + date;
    }
}

在JSP页面中添加表单,并在表单中传输2020-10-10格式的日期数据

<%--自定义类型转换器--%>
<form action="param/saveDate" method="post">
    日期:<input type="text" name="date">
    <input type="submit" value="提交">
</form>

执行测试代码:

/**
 * 自定义类型转换器
 * @param dateType
 * @return
 */
@RequestMapping("/deleteDate")
public String deleteDate(DateType date){
    System.out.println("执行了...");
    System.out.println(date);
    return "success";
}

上边代码执行过后会发现报错,因为SpringMVC不能解析这个数据,这时需要我们自定义类型转换器:

  • 第一步:定义一个类,实现 Converter 接口
public class StringToDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        //判断
        if(source==null){
            throw new RuntimeException("请您传入数据");
        }
        DateFormat df=new SimpleDateFormat("yyy-MM-dd");

        try{
            //把字符串转换为日期
            return df.parse(source);
        }catch (Exception e){
            throw new RuntimeException("数据类型转换出现错误");
        }

    }
}

  • 第二步:在 spring 配置文件中配置类型转换器,spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去。
<!--配置自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <!--类型转换器的路径-->
            <bean class="com.ly.utils.StringToDateConverter"></bean>
        </set>
    </property>
</bean>
  • 第三步:在 annotation-driven 标签中引用配置的类型转换服务
<!-- 引用自定义类型转换器 --> 
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>

这样就是先自定义类型转换了。

使用 ServletAPI 对象作为方法参数
SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。支持原始 ServletAPI 对象有:HttpServletRequest 、HttpServletResponse、HttpSession…我们可以把这些对象,直接写在控制的方法参数中使用,在控制器中使用原生的ServletAPI对象,只需要在控制器的方法参数定义对应对象即可。

<!-- 原始 ServletAPI 作为控制器参数 --> 
<a href="account/testServletAPI">测试访问 ServletAPI</a>

控制器中的代码:

/**
 * 测试访问 testServletAPI
 */
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,HttpServletResponse response,HttpSession session) {
	System.out.println(request);
	System.out.println(response);
	System.out.println(session);
	return "success"; 
}

REST 风格 URL

REST(英文:Representational State Transfer,简称 REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种 Web 服务交互方案中,REST 相比于 SOAP(Simple Object Access protocol,简单对象访问协议)以及 XML-RPC 更加简单明了,无论是对 URL 的处理还是对 Payload 的编码,REST 都倾向于用更加简单轻量的方法设计和实现。值得注意的是 REST 并没有一个明确的标准,而更像是一种设计的风格,它本身并没有什么实用性,其核心价值在于如何设计出符合 REST 风格的网络接口。
优点:结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
特性:

  • 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息,它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个 URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的 URI 就可以,因此 URI 即为每一个资源的独一无二的识别符。 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层 (Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
  • 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。
    HTTP 协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET 、POST 、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

基于 HiddentHttpMethodFilter 的示例
由于浏览器 form 表单只支持 GET 与 POST 请求,而 DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法,使得支持 GET、POST、PUT 与 DELETE 请求。
使用方法:

  • 第一步:在 web.xml 中配置该过滤器。
  • 第二步:请求方式必须使用 post 请求。
  • 第三步:按照要求提供_method 请求参数,该参数的取值就是我们需要的请求方式。
    源码分析:
    jsp 中示例代码:
<!-- 保存 --> 
<form action="springmvc/testRestPOST" method="post">
	用户名称:<input type="text" name="username"><br/>
	<!-- <input type="hidden" name="_method" value="POST"> --> 
	<input type="submit" value="保存">
</form> <hr/>
<!-- 更新 --> 
<form action="springmvc/testRestPUT/1" method="post">
	用户名称:<input type="text" name="username"><br/>
	<input type="hidden" name="_method" value="PUT"> 
	<input type="submit" value="更新">
</form>
<hr/>
<!-- 删除 --> 
<form action="springmvc/testRestDELETE/1" method="post"> 
	<input type="hidden" name="_method" value="DELETE"> 
	<input type="submit" value="删除">
</form> <hr/>
<!-- 查询一个 --> 
<form action="springmvc/testRestGET/1" method="post"> 
	<input type="hidden" name="_method" value="GET"> 
	<input type="submit" value="查询">
</form> 

控制器中示例代码:

/**
* post 请求:保存
* @param username
* @return
*/
@RequestMapping(value="/testRestPOST",method=RequestMethod.POST)
public String testRestfulURLPOST(User user){
	System.out.println("rest post"+user);
	return "success"; 
}
/**
* put 请求:更新
* @param username
* @return
*/
@RequestMapping(value="/testRestPUT/{id}",method=RequestMethod.PUT)
public String testRestfulURLPUT(@PathVariable("id")Integer id,User user){
	System.out.println("rest put "+id+","+user);
	return "success"; 
}
/**
* post 请求:删除
* @param username
* @return
*/
@RequestMapping(value="/testRestDELETE/{id}",method=RequestMethod.DELETE)
public String testRestfulURLDELETE(@PathVariable("id")Integer id){
	System.out.println("rest delete "+id);
	return "success"; 
}
/**
* post 请求:查询
* @param username
* @return
*/
@RequestMapping(value="/testRestGET/{id}",method=RequestMethod.GET)
public String testRestfulURLGET(@PathVariable("id")Integer id){
	System.out.println("rest get "+id);
	return "success"; 
} 

运行结果:
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙源lll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值