假设我有一个页面,列出了一个表上的对象,我需要放一个表单来过滤表。过滤器作为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) { ... }
假设我有MyObject为:
public class MyObject {
private String prop1;
private String prop2;
private String prop3;
//Getters and setters
...
}
我想做的是:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "myObject", required = false) MyObject myObject,) { ... }
这可能吗?
我该怎么做呢?
我将添加一些简短的例子。
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);
}
}
控制器类内部的请求映射:
@RequestMapping(value="/handle", method=RequestMethod.GET)
@ResponseBody
public String handleRequest(SearchDTO search) {
LOG.info("criteria: {}", search);
return "OK";
}
查询:
http://localhost:8080/app/handle?id=353,234
结果:
[http-apr-8080-exec-7] INFO c.g.g.r.f.w.ExampleController.handleRequest:59 - criteria: SearchDTO[id={353,234}]
我希望它能帮助你:)
更新/ kotlin
因为目前我正在大量使用Kotlin,如果有人想定义类似的DTO, Kotlin中的类应该有以下形式:
class SearchDTO {
var id: Array<Long>? = arrayOf()
override fun toString(): String {
// to string implementation
}
}
使用像这样的数据类:
data class SearchDTO(var id: Array<Long> = arrayOf())
Spring(在Boot中测试)对于answer中提到的请求返回以下错误:
“转换java.lang类型的值失败。字符串[]'到所需的类型
“java.lang.Long[]”;嵌套异常为
java.lang.NumberFormatException:用于输入字符串:\"353,234\""
data类只对以下请求参数表单有效:
http://localhost:8080/handle?id=353&id=234
要注意这一点!
接受的答案就像一个魅力,但如果对象有一个对象列表,它不会像预期的那样工作,所以这里是我的解决方案后,一些挖掘。
遵循这个线程建议,以下是我的做法。
Frontend: stringalize你的对象,而不是在base64编码提交。
后端:解码base64字符串,然后将字符串json转换为所需的对象。
它不是最好的调试你的API与邮差,但它是为我工作预期。
原始对象:{页:1,大小:5,过滤器:[{字段:“id”,值:1,比较:“EQ”}
编码对象:eyJwYWdlIjoxLCJzaXplIjo1LCJmaWx0ZXJzIjpbeyJmaWVsZCI6ImlkUGFyZW50IiwiY29tcGFyaXNvbiI6Ik5VTEwifV19
@GetMapping
fun list(@RequestParam search: String?): ResponseEntity<ListDTO> {
val filter: SearchFilterDTO = decodeSearchFieldDTO(search)
...
}
private fun decodeSearchFieldDTO(search: String?): SearchFilterDTO {
if (search.isNullOrEmpty()) return SearchFilterDTO()
return Gson().fromJson(String(Base64.getDecoder().decode(search)), SearchFilterDTO::class.java)
}
这里是SearchFilterDTO和FilterDTO
class SearchFilterDTO(
var currentPage: Int = 1,
var pageSize: Int = 10,
var sort: Sort? = null,
var column: String? = null,
var filters: List<FilterDTO> = ArrayList<FilterDTO>(),
var paged: Boolean = true
)
class FilterDTO(
var field: String,
var value: Any,
var comparison: Comparison
)