Spring MVC使用Model接收带有【特殊字符】的请求值最佳实践

6 篇文章 0 订阅

前言

单纯为了解决问题,请直接下跳转【最佳实践->第三种方案】。

Spring MVC使用时候wield便于数据传输,都会使用Model进行接收参数,见实例:
请求:

127.0.0.1:8080/test?myName=zs&myAge=10

接收请求:

@GetMapping("/demo")
public R<String> query(Demo demo) {
	// 调用具体服务
	service.server(demo);
	return R.ok(“业务处理完毕”);
}

接收实体:

class Demo {
	private String myName;
	private String myAge;

	public void setMyName(String myName) {
		this.myName = myName;
	}

	public void setMyAge(String myAge) {
		this.myAge = myAge;
	}
}

那如果请求的变成下列这样(带了字符),在不改变接收参数的开发习惯下(驼峰命名)该怎么解决?

127.0.0.1:8080/test?my_name=zs&my_age=10

最佳实践

对于这种的127.0.0.1:8080/test?my_name=zs&my_age=10请求,有多种解决方案:

第一种:使用@RequestParam

见实例,这种的比较笨,需要手动赋值,显然没有交给Spring MVC去处理来的轻松。

@GetMapping("/demo")
	public R<String> query(@RequestParam(name = "my_name", required = false) String myName,
	                                    @RequestParam(name = "my_age", required = false) String myAge) {
		final Demo demo = new Demo();
		demo.setMyName(myName);
		demo.setMyAge(myAge);
		// 调用具体服务
		service.server(demo);
		return R.ok("业务处理完毕");
	}

第二种:改变setter方法

见下图,接收仍然是对象,尽管能运行,但强迫症使我接收不了啊,不论是属性还是Setter方法变得太难受了,怎么办,最佳实践肯定有好的解决办法,见第三。

@GetMapping("/demo")
public R<String> query(Demo demo) {
	// 调用具体服务
	service.server(demo);
	return R.ok(“业务处理完毕”);
}

class Demo {
	private String myName;
	// 直接赋值
	private String my_age;
	
	// 通过setter赋值
	public void setMy_name(String myName) {
		this.myName = myName;
	}
 
}

第三种:使用@ConstructorProperties

使用@ConstructorProperties标记构造方法即可完美解决问题,强迫症终于治愈了

public R<String> query(Demo demo) {
	// 调用具体服务
	service.server(demo);
	return R.ok(“业务处理完毕”);
}


class Demo {
	private String myName;
	private String myAge;

	@ConstructorProperties({"my_name", "my_age"})
	public Demo(String myName, String myAge) {
		this.myName = myName;
		this.myAge = myAge;
	}
	public void setMyName(String myName) {
		this.myName = myName;
	}

	public void setMyAge(String myAge) {
		this.myAge = myAge;
	}
}

源码截图

Spring MVC解析参数并绑定对象的处理类:org.springframework.web.method.annotation.ModelAttributeMethodProcessor
具体方法:
constructAttribute(java.lang.reflect.Constructor<?>, java.lang.String, org.springframework.core.MethodParameter, org.springframework.web.bind.support.WebDataBinderFactory, org.springframework.web.context.request.NativeWebRequest)

		
		// 通过构造方法构建,然而这里并没有做任何事,固定返回null
		Object constructed = constructAttribute(ctor, attributeName, binderFactory, webRequest);
		if (constructed != null) {
			return constructed;
		}

		// 构造方法是个无惨构造方法
		if (ctor.getParameterCount() == 0) {
			// 那么只能通过setter 或 直接属性赋值了,对应改变setter 和属性值
			return BeanUtils.instantiateClass(ctor);
		}

		// 没错,就是这里了通过有参构造器注入,同时呢,他会去看一个注解,
		// 就是我们用的@ConstructorProperties,当然如果请求参数和构造参数完全一致,那就不需要该注解了。
		ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
		String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
		Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
		Class<?>[] paramTypes = ctor.getParameterTypes();
		...省略...
		return BeanUtils.instantiateClass(ctor, args);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值