Spring Boot控制器返回通用类型(A或B)。

huangapple go评论107阅读模式
英文:

Spring Boot Controller return generic types (A or B)

问题

您的控制器函数中使用的ResponseMessage<?>中的问号?并不是最好的方式,您可以使用Java的通配符<? extends T>来更好地表示返回值,其中TResponseMessage的类型参数。这将更准确地表明您的函数可能返回不同类型的ResponseMessage。这是一个更新后的示例:

  1. public ResponseMessage<? extends Object> findRecent(@AuthenticationPrincipal LoginUser user) {
  2. Optional<TodoResponse> todo = todoService.findRecent(user.getId());
  3. return todo.isPresent() ? ResponseMessage.ok(todo.get()) : ResponseMessage.noContent();
  4. }

在这种情况下,您的findRecent函数可以返回ResponseMessage<TodoResponse>ResponseMessage<String>,具体取决于todoService.findRecent的返回值。这种方式更具灵活性,同时仍然提供了类型安全。

英文:

I develop simple todo-list application with spring boot. And I wanna send common response dto from all request. The data filed in ReponseMessage is Generic because it can be various type.

  1. public class ResponseMessage&lt;T&gt; {
  2. private int statusCode = HttpStatus.OK.value();
  3. private String message = &quot;&quot;;
  4. protected T data; // this is generic. it can be many response dto.
  5. public static ResponseMessage&lt;String&gt; ok() {
  6. return new ResponseMessage&lt;&gt;(&quot;&quot;);
  7. }
  8. public static &lt;T&gt; ResponseMessage&lt;T&gt; ok(T data) {
  9. return new ResponseMessage&lt;&gt;(data);
  10. }
  11. public static ResponseMessage&lt;Object&gt; noContent() {
  12. return new ResponseMessage&lt;&gt;(HttpStatus.NO_CONTENT.value(), HttpStatus.NO_CONTENT.getReasonPhrase(), &quot;&quot;);
  13. }
  14. protected ResponseMessage(T data) {
  15. this.data = data;
  16. }
  17. private ResponseMessage(int statusCode, String message, T data) {
  18. this.statusCode = statusCode;
  19. this.message = message;
  20. this.data = data;
  21. }
  22. protected ResponseMessage() {}
  23. public int getStatusCode() {
  24. return statusCode;
  25. }
  26. public String getMessage() {
  27. return message;
  28. }
  29. public T getData() {
  30. return data;
  31. }
  32. }

Now i need to make a feature that find a recend todo.

If todo exists, send ResponseMessage<TodoResponse>.

  1. {
  2. &quot;statusCode&quot;: 200,
  3. &quot;message&quot;: &quot;&quot;,
  4. &quot;data&quot;: [
  5. {
  6. &quot;id&quot;: 1,
  7. &quot;title&quot;: &quot;test&quot;,
  8. &quot;status&quot;: &quot;TODO&quot;
  9. }
  10. ]
  11. }

If todo doesn't exist, send ResponseMessage<Srring>.

  1. {
  2. &quot;statusCode&quot;: 200,
  3. &quot;message&quot;: &quot;&quot;,
  4. &quot;data&quot;: []
  5. }

Now my controller function return like this.

  1. public ResponseMessage&lt;?&gt; findRecent(@AuthenticationPrincipal LoginUser user) {
  2. Optional&lt;TodoResponse&gt; todo = todoService.findRecent(user.getId());
  3. return todo.isPresent() ? ResponseMessage.ok(todo.get()) : ResponseMessage.noContent();
  4. }

I know that the question mark '?' is not good. so what is better way to return A or B in this case? plz help me.

答案1

得分: 1

如果将noContent().data设置为null,您可以安全地分配任何类型:

  1. public static <T> ResponseMessage<T> noContent() {
  2. return new ResponseMessage<>(HttpStatus.NO_CONTENT.value(), HttpStatus.NO_CONTENT.getReasonPhrase(), null);
  3. }

另外,请注意调用Optional.isPresent()然后再调用get()有点类似反模式。在您的情况下,您可以简化为:

  1. return todoService.findRecent(user.getId())
  2. .map(ResponseMessage::ok)
  3. .orElseGet(ResponseMessage::noContent);
英文:

If you set noContent().data to null, you can safely assign it any type:

  1. public static &lt;T&gt; ResponseMessage&lt;T&gt; noContent() {
  2. return new ResponseMessage&lt;&gt;(HttpStatus.NO_CONTENT.value(), HttpStatus.NO_CONTENT.getReasonPhrase(), null);
  3. }

Also note that calling Optional.isPresent() and then get() is something of an antipattern. In your case, you can simplify it to this:

  1. return todoService.findRecent(user.getId())
  2. .map(ResponseMessage::ok)
  3. .orElseGet(ResponseMessage::noContent);

huangapple
  • 本文由 发表于 2023年2月16日 05:09:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75465456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定