处理提交过来的数据
提交的域名称与方法中的参数名一致
- 没啥说的,自动封装
http://localhost:8081/springmvc_2/sout?name=APP&phone=1008611
@RequestMapping("sout")
public String test(String name,String phone){
System.out.println(name);
System.out.println(phone);
//不进行任何操作
return null;
}
//输出APP 1008611
提交的域名称与方法中的参数名不一致
-
如果取请求过来的name与方法中的参数名不一致,就不能封装上,为NULL
-
使用@RequestParam注解,将域名称与方法参数进行绑定
http://localhost:8081/springmvc_2/sout?uuu=PPP&ppp=121212
@RequestMapping("sout")
public String test(@RequestParam("uuu") String name, @RequestParam("ppp") String phone){
System.out.println(name);
System.out.println(phone);
//不进行任何操作
return null;
}
提交一个对象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private String pwd;
}
http://localhost:8081/springmvc_2/login?id=123&name=Poer&pwd=123
@RequestMapping("login")
public String login(User user){
System.out.println(user);
return null;
}
提交的域名城要与封装的实体类属性名一致,不然为null
自定义工具类实现对象自动封装
- 工具类
package com.mlyr.d;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @Author 陌路邑人
* @Date
* @Project
*/
public class MapUtils {
public static Object MapToObject(Map<String, String[]> parameterMap, Class clazz) {
Set<String> keySet = parameterMap.keySet();//先获取map集合的所有key
Iterator<String> iterator = keySet.iterator();//迭代这个key
Object o = null;
try {
o = clazz.newInstance();
while (iterator.hasNext()){
String key = iterator.next();//获取map的key
Field field = clazz.getDeclaredField(key);//根据key值找到要封装的类对应的属性
field.setAccessible(true);//打破封装
String[] values = parameterMap.get(key);//根据key获取value
Class<?> type = field.getType();//获取属性的数据类型
//根据属性的数据类型不同,转换与之对应的数据类型进行封装
if (type==Integer.class){
field.set(o,Integer.parseInt(values[0]));
}else{
field.set(o,values[0]);
}
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return o;
}
}
- controller
@RequestMapping("login")
public String login(HttpServletRequest request, HttpServletResponse response){
//获取请求参数map
Map<String, String[]> parameterMap = request.getParameterMap();
//自定义对象封装
User user = (User)MapUtils.MapToObject(parameterMap,User.class);
System.out.println(user);
return null;
}
处理请求中的时间类型数据
- 首先会报错,
Field error in object 'user' on field 'date': rejected value [2021-03-03]; codes [typeMismatch.user.date,typeMismatch.date,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2021-03-03'; nested exception is java.lang.IllegalArgumentException]]
第一种解决方案
- 需要自定义一个类来处理全局的日期转换,把页面请求过来的字符串转换为Date类型的数据
package com.mlyr.f;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author 陌路邑人
* @Date
* @Project 日期转换
*/
public class DateConvert implements Converter<String, Date> {
String format1 = "yyyy-MM-dd";
String format2 = "yyyy/MM/dd";
SimpleDateFormat format = null;
@Override
public Date convert(String source) {
format = new SimpleDateFormat(format1);
Date date = null;
try {
date = format.parse(source);
} catch (ParseException e) {
format = new SimpleDateFormat(format2);
try {
date = format.parse(source);
} catch (ParseException parseException) {
parseException.printStackTrace();
}
}
return date;
}
}
- 还要在mvc配置文件中配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描指定包下加有注解的放入spring容器中-->
<context:component-scan base-package="com.mlyr.f"/>
<!--指向自定义的日期转换Bean-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--配置日期转换器-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<!--注入自定义的日期转换器-->
<bean class="com.mlyr.f.DateConvert"></bean>
</set>
</property>
</bean>
</beans>
第二种解决方案
- 在实体类上加
@DateTimeFormat(pattern = "yyyy-MM-dd")
- 只能解决局部的类中的日期类型映射
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private String pwd;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
}
@RequestBody
-
@RequestBody
注解可以接收json格式的数据,并将其转换成对应的数据类型 -
在使用之前一定要导入一个依赖,不然会报415错误
-
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.1</version> </dependency>
-
还有要设置传过去的是json数据,请求类型为
contentType : "application/json;charset=UTF-8"
-
还有要在mvc配置文件中配置
<mvc:annotation-driven/>
@RequestMapping("app")
public String app(@RequestBody User user){
System.out.println("APP+"+user);
return null;
}
<button type="button" id="btn">按钮</button>
<script>
$("#btn").click(function (){
$.ajax({
url: "app",
type: "post",
dataType:"json",
//headers contentType 选其一设置去请求类型
// headers: {'Content-type': 'application/json;charset=UTF-8'},
contentType : "application/json;charset=UTF-8",
data: JSON.stringify({"name": "ADD", "pwd": "1234"}),
success: function (data) {
alert(data)
}
})
})
</script>
还有一种是自定义一个消息转换器
- 自定义消息转换器
public class UserHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
@Override
protected boolean supports(Class<?> clazz) {
return true;
}
@Override
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
System.out.println("=========");
//获取到从页面传递过来的字符串
InputStream body = inputMessage.getBody();
byte[] bytes = new byte[1024];
body.read(bytes);//将输入流中的数据读到byte数组中去
String str = new String(bytes).trim();//将数组转换为字符串,并去除掉多余的空格 name=AAA&pwd=123
String[] strings = str.split("&");//将传过来的字符串先按照&进行分割 {name=AAA,pwd=123}
Object obj = null;
try {
obj = clazz.newInstance();
for (String string : strings) {
String[] ss = string.split("=");//再将分割后的字符串数组再以=进行分割 此时ss[0]=name,ss[1]=AAA
Field declaredField = clazz.getDeclaredField(ss[0]);//反射获取对应的属性
declaredField.setAccessible(true);//打破封装
declaredField.set(obj,ss[1]);//赋值
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return obj;
}
@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
}
}
- 在mvc中配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描指定包下加有注解的放入spring容器中-->
<context:component-scan base-package="com.mlyr.j"/>
<mvc:annotation-driven>
<!--配置消息转换器-->
<mvc:message-converters register-defaults="true">
<!--自定义的信息转换器-->
<bean class="com.mlyr.j.UserHttpMessageConverter">
<property name="supportedMediaTypes" >
<!--配置转换的数据格式-->
<list>
<value>application/x-www-form-urlencoded</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
- 发送的请求
<button type="button" id="btn">按钮</button>
<script>
$("#btn").click(function (){
$.ajax({
url: "app",
type: "post",
dataType:"json",
//headers contentType 选其一设置去请求类型
// headers: {'Content-type': 'application/json;charset=UTF-8'},
// contentType : "application/json;charset=UTF-8",
// data: JSON.stringify({"name": "ADD", "pwd": "1234"}),
data:{"name": "ADD", "pwd": "1234"},
success: function (data) {
alert(data)
}
})
})
</script>
注意:
- 这个自定义的消息转换器只能转换传过来的key=value这种形式的数据,json格式的转换不了
- 当然他与SpringMVC默认的json格式转换可以共同使用,不影响,传过来的如果是 contentType : "application/json;charset=UTF-8",
data: JSON.stringify({"name": "ADD", "pwd": "1234"}), 的他就会不走自定义的转换器- data:{"name": "ADD", "pwd": "1234"} 会走自定义的消息转换器