我有一个Command Object
的控制器,它使用泛型,如下所示:
@Controller
@RequestMapping(value = "/first")
public class MyFirstController {
@RequestMapping(value = "/something", method = RequestMethod.POST)
@ResponseBody
public ADifferentDTO doSomething(RequestDTO<MyStringObject> requestDTO, HttpServletRequest request,
HttpServletResponse response) {
requestDTO.getSomeObject(); // ERROR HERE
//.. do something
}
}
然而,这不起作用。我认为它因Java中的Type Erasure而无法正常工作。有没有办法让Command对象使用泛型? 以下是其他一些类的内容。
public class RequestDTO<T> {
private T someObject;
// some other objects here as well that are from a submitted form (not listed)
public void setSomeObject(T someObject){
this.someObject = someObject;
}
public T getSomeObject(){
return someObject;
}
}
public class MyStringObject {
private String someString;
public MyStringObject(String someString){
this.someString = someString;
}
// getter and setter
}
public class MyIntegerObject {
private Integer someInteger;
private Integer anotherInteger;
public MyIntegerObject(Integer someInteger, Integer anotherInteger){
this.someInteger = someInteger;
this.anotherInteger = anotherInteger;
}
// getter and setter
}
我得到的错误:
java.lang.Object cannot be cast to com.test.MyStringObject
当然,如果我将RequestDTO
更改为仅使用MyStringObject
,则可以正常使用。
public class RequestDTO {
private MyStringObject someObject;
// some other objects here as well that are from a submitted form (not listed)
public void setSomeObject(MyStringObject someObject){
this.someObject = someObject;
}
public MyStringObject getSomeObject(){
return someObject;
}
}
有没有办法可以做到这一点?
答案 0 :(得分:1)
你是对的,这是因为类型擦除。
可能最简单的解决方案是创建一个RequestDTO子类,使用每个My * Object参数化,并将其用作命令对象类。
鉴于你的例子:
@SpringBootApplication
public class So44423504Application {
public static void main(String[] args) {
SpringApplication.run(So44423504Application.class, args);
}
@RestController
@RequestMapping(value = "/first")
public static class MyFirstController {
public static class MyStringRequestDTO extends RequestDTO<MyStringObject> {}
public static class MyIntegerRequestDTO extends RequestDTO<MyIntegerObject> {}
@PostMapping(value = "/something")
public String doSomething(@ModelAttribute MyStringRequestDTO/*MyIntegerRequestDTO*/ requestDTO) throws JsonProcessingException {
return new ObjectMapper().writeValueAsString(requestDTO);
}
}
public static class RequestDTO<T> {
private T someObject;
// getter and setter
}
public static class MyStringObject {
private String someString;
public MyStringObject() { } // required since another non-default ctor is present.
public MyStringObject(String someString){
this.someString = someString;
}
// getter and setter
}
public static class MyIntegerObject {
private Integer someInteger;
private Integer anotherInteger;
public MyIntegerObject() { } // required since another non-default ctor is present.
public MyIntegerObject(Integer someInteger, Integer anotherInteger){
this.someInteger = someInteger;
this.anotherInteger = anotherInteger;
}
// getters and setters
}
}
然后它工作正常:
$ curl -XPOST 'localhost:8080/first/something?someObject.someInteger=23&someObject.anotherInteger=42'
{"someObject":{"someInteger":23,"anotherInteger":42}}%
$ curl -XPOST 'localhost:8080/first/something?someObject.someString=test'
{"someObject":{"someString":"test"}}%