简体   繁体   English

(无)参数构造函数的最佳方式 - ResponseBody - Spring

[英]The best way for (no) argument constructor - ResponseBody - Spring

Let me introduce my code then I will ask a question.让我介绍一下我的代码,然后我会问一个问题。 This is just an example.这只是一个例子。 I would like to learn something new if it is possbile.如果可能的话,我想学习一些新的东西。

BaseClass.java基类.java

public class BaseClass {

  private String baseName;

  BaseClass(String baseName){
    this.baseName = baseName;
  }
  //getters and setters
}

MyClass.java我的类

public class MyClass extends BaseClass {

  private boolean isTest;
  private String name;

  MyClass(){
  }

  MyClass(String baseName){
    super(baseName);
    this.isTest = true;
  }
  //getters and setters
}

MyClassController.java MyClassController.java

@Controller
public class MyClassController {

  @GetMapping(value="/")
  @ResponseBody
  public String myClassController(@RequestBody MyClass myClass) {


    return "index";
  }
}

JSON request: JSON 请求:

{
  "name": "Name for BaseClass"
}

So, I send name eg: Name for BaseClass .所以,我发送名称,例如: Name for BaseClass I want to set this name for variable BaseName in BaseClass through constructor.我想通过构造函数为 BaseClass 中的变量BaseName设置这个名称。 @RequestBody needs no atribute constructor so I cannot use there this second constructor with arguments. @RequestBody不需要属性构造函数,所以我不能在那里使用带有参数的第二个构造函数。 I can handle this eg for using additional method:我可以处理这个,例如使用其他方法:

Additional method in MyClass.java MyClass.java 中的附加方法

  public MyClass setValues(String baseName){
    super(baseName);
    this.isTest = true;
    return this;
  }

New MyController.java新建 MyController.java

@Controller
public class MyClassController {

  @GetMapping(value="/")
  @ResponseBody
  public String myClassController(@RequestBody MyClass myClass) {

    myClass.setValues(myClass.getName());
    //more uses for myClass

    return "index";
  }
}

Is there any better way to do something like this in more "professional" way?有没有更好的方法以更“专业”的方式做这样的事情?

If you're married to the current inheritance structure, you can use HttpMessageConverter to customize the way Spring deserializes HTTP requests.如果您已经接受了当前的继承结构,则可以使用 HttpMessageConverter 来自定义 Spring 反序列化 HTTP 请求的方式。

public class MyClassConverter extends AbstractHttpMessageConverter<MyClass> {

  public MyClassConverter() {
      super(new MediaType("text", "myClass"));
  }

  @Override
  protected boolean supports(Class<?> clazz) {
      return MyClass.class.isAssignableFrom(clazz);
  }

  @Override
  protected MyClass readInternal(Class<? extends MyClass> clazz, HttpInputMessage inputMessage)
          throws IOException, HttpMessageNotReadableException {

      // Deserialize JSON request

      MyClass inputObject = new MyClass(name);
      return inputObject;
  }

  @Override
  protected void writeInternal(MyClass myClass, HttpOutputMessage outputMessage) {

      // Serialize MyClass object

  }
}

Detailed example 详细示例

Although it's not clear I'm assuming name and baseName are meant to be the same value.虽然不清楚我假设 name 和 baseName 是相同的值。 In that case it might make sense for BaseClass to be an abstract class or interface.在这种情况下,将 BaseClass 作为抽象类或接口可能是有意义的。

abstract class:抽象类:

public class MyClass extends BaseClass {

    private String name;

    // constructors

    @Override
    String getName() {
        return name;
    }

    // setters
}

public abstract class BaseClass {
    abstract String getName();
}

interface:界面:

public class MyClass implements DtoWithName {

    private String name;

    // constructors

    @Override
    String getName() {
        return name;
    }

    // setters
}

public interface DtoWithName {
    String getName();
}

Also, I can't tell much about your use-case from the given example, but you should read into Composition over inheritance to make sure you're going about it the right way.另外,我无法从给定的示例中详细说明您的用例,但是您应该阅读组合而不是继承以确保您以正确的方式进行操作。 With DTOs in particular usually simple is best.特别是对于 DTO,通常简单是最好的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM