ren*_*rof 175 java spring-mvc
假设我有一个列出表中对象的页面,我需要放置一个表单来过滤表.过滤器作为Ajax GET发送到如下URL:http://foo.com/system/controller/action?page = 1&prop1 = x&prop2 = y&prop3 = z
而不是在我的控制器上有很多参数,如:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "prop1", required = false) String prop1,
@RequestParam(value = "prop2", required = false) String prop2,
@RequestParam(value = "prop3", required = false) String prop3) { ... }
Run Code Online (Sandbox Code Playgroud)
假设我有MyObject:
public class MyObject {
private String prop1;
private String prop2;
private String prop3;
//Getters and setters
...
}
Run Code Online (Sandbox Code Playgroud)
我想做的事情如下:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "myObject", required = false) MyObject myObject,) { ... }
Run Code Online (Sandbox Code Playgroud)
可能吗?我怎样才能做到这一点?
Bij*_*men 225
你绝对可以这样做,只需删除@RequestParam
注释,Spring会将你的请求参数干净地绑定到你的类实例:
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
MyObject myObject)
Run Code Online (Sandbox Code Playgroud)
Prz*_*wak 50
我将添加一些简短的例子.
DTO课程:
public class SearchDTO {
private Long id[];
public Long[] getId() {
return id;
}
public void setId(Long[] id) {
this.id = id;
}
// reflection toString from apache commons
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
Run Code Online (Sandbox Code Playgroud)
控制器类内的请求映射:
@RequestMapping(value="/handle", method=RequestMethod.GET)
@ResponseBody
public String handleRequest(SearchDTO search) {
LOG.info("criteria: {}", search);
return "OK";
}
Run Code Online (Sandbox Code Playgroud)
查询:
http://localhost:8080/app/handle?id=353,234
Run Code Online (Sandbox Code Playgroud)
结果:
[http-apr-8080-exec-7] INFO c.g.g.r.f.w.ExampleController.handleRequest:59 - criteria: SearchDTO[id={353,234}]
Run Code Online (Sandbox Code Playgroud)
我希望它有帮助:)
更新/ KOTLIN
因为目前我和Kotlin一起工作很多,如果有人想要定义类似的DTO,Kotlin中的类应该具有以下形式:
class SearchDTO {
var id: Array<Long>? = arrayOf()
override fun toString(): String {
// to string implementation
}
}
Run Code Online (Sandbox Code Playgroud)
data
像这样的班级:
data class SearchDTO(var id: Array<Long> = arrayOf())
Run Code Online (Sandbox Code Playgroud)
Spring(在Boot中测试)为回答中提到的请求返回以下错误:
"无法将'java.lang.String []'类型的值转换为必需类型'java.lang.Long []';嵌套异常是java.lang.NumberFormatException:对于输入字符串:\"353,234 \""
数据类仅适用于以下请求参数形式:
http://localhost:8080/handle?id=353&id=234
Run Code Online (Sandbox Code Playgroud)
请注意这一点!
Flu*_*ode 11
由于每个帖子下都会弹出如何设置必填字段的问题,我写了一个关于如何设置必填字段的小例子:
public class ExampleDTO {
@NotNull
private String mandatoryParam;
private String optionalParam;
@DateTimeFormat(iso = ISO.DATE) //accept Dates only in YYYY-MM-DD
@NotNull
private LocalDate testDate;
public String getMandatoryParam() {
return mandatoryParam;
}
public void setMandatoryParam(String mandatoryParam) {
this.mandatoryParam = mandatoryParam;
}
public String getOptionalParam() {
return optionalParam;
}
public void setOptionalParam(String optionalParam) {
this.optionalParam = optionalParam;
}
public LocalDate getTestDate() {
return testDate;
}
public void setTestDate(LocalDate testDate) {
this.testDate = testDate;
}
}
//Add this to your rest controller class
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String testComplexObject (@Valid ExampleDTO e){
System.out.println(e.getMandatoryParam() + " " + e.getTestDate());
return "Does this work?";
}
Run Code Online (Sandbox Code Playgroud)
我有一个非常类似的问题.实际上问题是我想的更深.我$.post
使用的Content-Type:application/x-www-form-urlencoded; charset=UTF-8
是默认使用的jquery .不幸的是,我的系统基于此,当我需要一个复杂的对象时,@RequestParam
我不能让它发生.
在我的情况下,我试图用这样的东西发送用户偏好;
$.post("/updatePreferences",
{id: 'pr', preferences: p},
function (response) {
...
Run Code Online (Sandbox Code Playgroud)
在客户端,发送到服务器的实际原始数据是;
...
id=pr&preferences%5BuserId%5D=1005012365&preferences%5Baudio%5D=false&preferences%5Btooltip%5D=true&preferences%5Blanguage%5D=en
...
Run Code Online (Sandbox Code Playgroud)
解析为;
id:pr
preferences[userId]:1005012365
preferences[audio]:false
preferences[tooltip]:true
preferences[language]:en
Run Code Online (Sandbox Code Playgroud)
而服务器端是;
@RequestMapping(value = "/updatePreferences")
public
@ResponseBody
Object updatePreferences(@RequestParam("id") String id, @RequestParam("preferences") UserPreferences preferences) {
...
return someService.call(preferences);
...
}
Run Code Online (Sandbox Code Playgroud)
我尝试了@ModelAttribute
,添加了setter/getters,构造函数具有所有可能性,UserPreferences
但没有机会,因为它将发送的数据识别为5个参数,但实际上映射方法只有2个参数.我也试过了Biju的解决方案但是会发生的是,spring使用默认构造函数创建一个UserPreferences对象,并且不会填充数据.
我通过从客户端发送首选项的JSon字符串来解决问题,并将其处理为服务器端的字符串;
客户:
$.post("/updatePreferences",
{id: 'pr', preferences: JSON.stringify(p)},
function (response) {
...
Run Code Online (Sandbox Code Playgroud)
服务器:
@RequestMapping(value = "/updatePreferences")
public
@ResponseBody
Object updatePreferences(@RequestParam("id") String id, @RequestParam("preferences") String preferencesJSon) {
String ret = null;
ObjectMapper mapper = new ObjectMapper();
try {
UserPreferences userPreferences = mapper.readValue(preferencesJSon, UserPreferences.class);
return someService.call(userPreferences);
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
简而言之,我在REST方法中手动完成了转换.在我看来,spring无法识别发送数据的原因是内容类型.
归档时间: |
|
查看次数: |
166384 次 |
最近记录: |