表单中请求参数都是基于key=value的。SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。
如:
<a href="account/findAccount?accountId=10">查询账户</a>
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
System.out.println("查询了账户。"+accountId);
return "success";
}
支持的数据类型:
- 基本类型参数:包括基本类型和String类型
- POJO类型参数:包括实体类,以及关联的实体类
- 数组和集合类型参数:包括List结构和Map结构的集合(包括数组)
SpringMVC绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求。
使用要求:
- 基本类型参数:要求参数的名称必须和控制器中方法的形参名称保持一致。
- POJO类型参数:要求表单中参数名称和POJO类的属性名称保持一致,并且控制器方法的参数类型必须是POJO类型。
- 集合类型参数:第一种,要求集合类型请求参数必须是POJO中,在表单中请求参数名称要和POJO中集合属性名称相同。给List集合中的元素赋值,使用下标。给Map集合中的元素赋值,使用键值对;第二种,接收的请求参数是json格式数据,需要借助一个注解实现。
注意:自带的内置转换器可以实现一些数据类型自动转换。(org.springframework.core.convert.support)如遇特殊类型转换要求,需要自行定义类型转换器。
使用示例
一)基本类型和String类型作为参数
<fieldset> <h1>基本类型和String类型作为参数</h1> <a href="${pageContext.request.contextPath}/Account/find?accountId=2&accountName=张三">查询账户</a> </fieldset>
@Controller @RequestMapping("/Account") public class AccountController { @RequestMapping(value = "/find") public ModelAndView findAccount(Integer accountId,String accountName){ ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("message","账户信息"+accountId+"/"+accountName); modelAndView.setViewName("success"); return modelAndView; } }
二)POJO类型作为参数
public class Account { private Integer accountId; private String accountName; private float money; private Address address; @Override public String toString() { return "Account{" + "accountId=" + accountId + ", accountName='" + accountName + '\'' + ", money=" + money + ", address=" + address + '}'; } public Integer getAccountId() { return accountId; } public void setAccountId(Integer accountId) { this.accountId = accountId; } public String getAccountName() { return accountName; } public void setAccountName(String accountName) { this.accountName = accountName; } public float getMoney() { return money; } public void setMoney(float money) { this.money = money; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
public class Address implements Serializable { private String provinceName; private String cityName; @Override public String toString() { return "Address{" + "provinceName='" + provinceName + '\'' + ", cityName='" + cityName + '\'' + '}'; } public String getProvinceName() { return provinceName; } public void setProvinceName(String provinceName) { this.provinceName = provinceName; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } }
<fieldset> <h1>POJO类型作为参数</h1> <form method="post" action="${pageContext.request.contextPath}/Account/saveAccount"> 账户:<input name="accountName" type="text"><br> 资金:<input name="money" type="text"><br> 省份:<input name="address.provinceName" type="text"><br> 城市:<input name="address.cityName" type="text"><br> <input type="submit" value="保存"/> </form> </fieldset>
@RequestMapping("/saveAccount")
public ModelAndView saveAccount(Account account){
System.out.println(account);
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("message",account);
modelAndView.setViewName("success");
return modelAndView;
}
三)数组和集合类型参数
public class User implements Serializable { private String username; private String password; private Integer age; private List<Account> accounts; private Map<String,Account> accountMap; @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", age=" + age + ", accounts=" + accounts + ", accountMap=" + accountMap + '}'; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } public Map<String, Account> getAccountMap() { return accountMap; } public void setAccountMap(Map<String, Account> accountMap) { this.accountMap = accountMap; } }
<fieldset> <h1>数组和集合类型作为参数</h1> <form action="${pageContext.request.contextPath}/user/updateUser" method="post"> 用户名:<input name="username" type="text"><br> 密码:<input name="password" type="text"><br> 年龄:<input name="age" type="text"><br> 账户:<input name="accounts[0].accountName" type="text"><br> 资金:<input name="accounts[0].money" type="text"><br> 账户:<input name="accounts[1].accountName" type="text"><br> 资金:<input name="accounts[1].money" type="text"><br> 账户:<input name="accountMap['one'].accountName" type="text"><br> 资金:<input name="accountMap['one'].money" type="text"><br> 账户:<input name="accountMap['two'].accountName" type="text"><br> 资金:<input name="accountMap['two'].money" type="text"><br> <input type="submit" value="保存"> </form> </fieldset>
@Controller @RequestMapping("/user") public class UserController { @RequestMapping("/updateUser") public ModelAndView updateUser(User user){ System.out.println(user); ModelAndView modelAndView=new ModelAndView(); modelAndView.setViewName("success"); modelAndView.addObject("message",user); return modelAndView; } }
请求参数乱码问题
post请求方式
在web.xml中配置一个过滤器
<!--配置SpringMVC编码过滤器--> <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> <!--启动过滤器--> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!--过滤所有请求--> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
springMVC配置文件中可以配置,静态资源不过滤:
<!--location表示路径,mapping表示文件, **表示该目录下的文件以及子目录的文件--> <mvc:resources location="/css/" mapping="/css/**"/> <mvc:resources location="/images/" mapping="/images/**"/> <mvc:resources location="/scripts/" mapping="/javascript/**"/>
get请求方式
tomcat对GET和POST请求方式是不同的,GET请求的编码问题,要改tomcat的server.xml配置文件。
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> <!--改为--> <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>
如果遇到ajax请求仍然乱码,请把useBodyEncodingForURI="true"改为URIEncoding="UTF-8"即可。
RequestParam注解实现参数绑定
作用:把请求中指定名称的参数给控制器中的形参赋值。
属性:
- value:请求参数中的名称。
- required:请求参数中是否必须提供此参数。默认值:true,表示必须提供,如果不提供将报错。
使用示例
<fieldset> <h1>RequestParam注解参数绑定</h1> <a href="${pageContext.request.contextPath}/user/saveUser?name=张三">保存用户</a> </fieldset>
@RequestMapping("/saveUser")
public ModelAndView saveUser(@RequestParam("name") String username,@RequestParam(value = "age",required = false) Integer age){
System.out.println(username+" "+age);
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("success");
modelAndView.addObject("message",username+":"+age);
return modelAndView;
}
当url中没有传age参数时,不会报错。
自定义类型转换器
使用示例
<fieldset> <h1>自定义类型转换器</h1> <a href="${pageContext.request.contextPath}/user/getUser?date=2018-01-10">获取用户</a> </fieldset>
当控制器中的方法使用String去接收请求中的参数时是没有问题的。
@RequestMapping("/getUser")
public ModelAndView getUser(String date){
System.out.println(date);
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("success");
modelAndView.addObject("message",date);
return modelAndView;
}
而此时控制器中的方法使用Date去接收请求中的参数时就会报错。
@RequestMapping("/getUser")
public ModelAndView getUser(Date date){
System.out.println(date);
ModelAndView modelAndView=new ModelAndView();
modelAndView.setViewName("success");
modelAndView.addObject("message",date);
return modelAndView;
}

第一步:定义一个类,实现Converter接口。
public class StringToDateConverter implements Converter<String, Date> { @Override public Date convert(String s) { DateFormat format=null; try { if(s==null||s.isEmpty()){ throw new NullPointerException("输入字符串为空"); } format=new SimpleDateFormat("yyyy-MM-dd"); Date date = format.parse(s); return date; } catch (Exception e) { throw new RuntimeException("输入日期有误"); } } }
第二步:在spring配置文件中配置类型转换器。spring配置类型转换器的机制是,将自定义的转换器注册到类型转换器服务中去。
<!--配置类型转换器工厂--> <bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean"> <!--给工厂注入一个新的类型转换器--> <property name="converters"> <array> <!--配置自定义类型转换器--> <bean class="com.company.utils.StringToDateConverter"></bean> </array> </property> </bean>
第三步:在spring配置文件中,在annotation-driven标签中引用配置的类型转换服务。
<!--引用自定义类型转换器--> <mvc:annotation-driven conversion-service="conversionService2"></mvc:annotation-driven>
使用ServletAPI对象作为方法参数
SpringMVC还支持使用原始ServletAPI对象作为控制器方法的参数。支持原始ServletAPI对象有:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
可以把上述对象,直接写在控制的方法参数中使用。
<fieldset> <h1>ServletAPI作为参数</h1> <a href="${pageContext.request.contextPath}/user/testServletAPI">test servlet api</a> </fieldset>
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, HttpSession httpSession){
System.out.println(httpServletRequest);
System.out.println(httpServletResponse);
System.out.println(httpSession);
return "success";
}
消息头相关的两个注解
RequestHeader
作用:用于获取请求消息头。
属性:
- value:提供消息头名称
- required:是否必须有此消息头
注:在实际开发中一般不怎么用。
<fieldset> <h1>RequestHeader注解</h1> <a href="${pageContext.request.contextPath}/user/useRequestHeader">use Request Header</a> </fieldset>
@RequestMapping("/useRequestHeader")
public String useRequestHeader(@RequestHeader(value = "Accept-Language",required = false)String requestHeader){
System.out.println(requestHeader);
return "success";
}
CookieValue
作用:用于把指定cookie名称的值传入控制器方法参数。
属性:
- value:指定cookie的名称。
- required:是否必须有此cookie。
<fieldset> <h1>CookieValue注解</h1> <a href="${pageContext.request.contextPath}/user/useCookieValue">use Cookie Value</a> </fieldset>
@RequestMapping("/useCookieValue")
public String useCookieValue(@CookieValue(value = "JSESSIONID",required = false) String cookieValue){
System.out.println(cookieValue);
return "success";
}
posted on
浙公网安备 33010602011771号