springmvc/springboot关于 PropertyEditor的一个坑

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u013195275/article/details/89674453

定义一个名为Problem实体类,如下:

public class Problem implements java.io.Serializable {

	private static final long serialVersionUID = 5454155825314635342L;
	/**
	 * id
	 */
	private java.lang.String id;
	private java.lang.String problem;//问题描述

	public Problem() {
		// TODO 1. 看这里,虽然有一个缺省构造器
	}
	
	public Problem(java.lang.String id) {
		this.id = id;//2. 这个构造器一般为程序开发时,快捷构造对象使用
	}

	public java.lang.String getId() {
		return id;
	}

	public java.lang.String getProblem() {
		return problem;
	}

	public void setProblem(java.lang.String problem) {
		this.problem = problem;
	}

 
}

 因为设计时,就想着用户提的“问题内容”就用Problem类的problem属性保存。

请接口cotroller如下:

@Controller
@RequestMapping(value = "/test")
public class TestController extends BaseRestJSONController<CorpInfo, java.lang.String> {

	static Logger log = LoggerFactory.getLogger(TestController.class);
 
	@PostMapping("/problem")
	public @ResponseBody MReturnObject person(Problem test) throws Exception {
		return new MReturnObject(MReturnObject.ERROR, test);//3 按说test对象的id为null,test.problem的值为提交的内容
	}
	
}

1.请求/test/problem提交参数时problem=小区大门坏了,3处打印应为test.id为null,test.problem为“小区大门坏了”。

2.实际3处spring封装的test对象的属性值是test.id为“小区大门坏了”,test.problem的值也为“小区大门坏了”。

问题分析:

参考了资料,主要是《精通Spring 4.x  企业应用开发实战》第17章节

 17.3.2 数据转换

     .... 

    Java标准的PropertyEditor的核心功能是将一个字符串转换为一个Java对象,以便根据界面的输入或配置文件中的配置字符串构造出一一个JVM内部的Java对象。

      但是Java原生的PropertyEditor存在以下不足:

      只能用于字符串到Java对象的转换,不适用于任意两个Java类型之间的转换。

      对源对象及目标对象所在的上下文信息(如注解、所在宿主类的结构等)不敏感,在类型转换时不能利用这些上下文信息实施高级的转换逻辑。

      鉴于此,Spring 在核心模型中添加了-一个通用的类型转换模块,类型转换模块位于org.springframework. core.convert包中。Spring希望用这个类型转换体系替换Java标准的PropertyEditfor。但由于历史原因,Spring 将同时支持两者,在Bean配置、Spring MVC处理方法入参绑定中使用它们。

以上红色地方就说明了,当请求的参数名=入参对象定义的实体类名时,且该实体实现了“一个入参为字符串”的构造器,这时就会把problem的值(String)做为入参传入这个构造器反射生成对象,简单如下:
 

Problem problem=new Problem("小区大门坏了");//spring中是反射调用这个构造器,这里是形象说明问题,直接构造对象了

problem.setProblem("小区大门坏了");//此外为spring中生成对象后反射赋值。

所以虽然请求只提交了一个参数,但problem这两属性都赋了值。

1.如果Problem对象不定义一个“只含一个入参字符串”的构造器就不会产生上面的问题[上面实体赋值显然不是我们想要的结果]。

2.定义实体属性名时不要与实体名字相同。

3.提交的参数名不要与实体名相同[如果是为了业务或者利用这个现象另说],否则可能出其实现象。

猜你喜欢

转载自blog.csdn.net/u013195275/article/details/89674453