参数构造函数的最佳方法-ResponseBody-Spring

时间:2018-07-30 18:46:17

标签: java spring

让我介绍一下我的代码,然后我会问一个问题。 这只是一个例子。如果可能的话,我想学习一些新的东西。

BaseClass.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

@Controller
public class MyClassController {

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


    return "index";
  }
}

JSON请求:

{
  "name": "Name for BaseClass"
}

因此,我发送名称,例如: BaseClass的名称。我想通过构造函数为BaseClass中的变量 BaseName 设置此名称。 @RequestBody 不需要属性构造函数,因此我不能在此处使用第二个带有参数的构造函数。我可以解决这个问题使用其他方法:

MyClass.java中的其他方法

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

新的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";
  }
}

有没有更好的方法可以更“专业”地进行类似的事情?

2 个答案:

答案 0 :(得分:1)

如果您已嫁接到当前的继承结构,则可以使用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

答案 1 :(得分:0)

虽然目前尚不清楚,但我假设name和baseName是相同的值。在这种情况下,将BaseClass用作抽象类或接口可能很有意义。

抽象类:

public class MyClass extends BaseClass {

    private String name;

    // constructors

    @Override
    String getName() {
        return name;
    }

    // setters
}

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

界面:

public class MyClass implements DtoWithName {

    private String name;

    // constructors

    @Override
    String getName() {
        return name;
    }

    // setters
}

public interface DtoWithName {
    String getName();
}

此外,在给定的示例中,我无法充分说明您的用例,但是您应该阅读Composition over inheritance,以确保您以正确的方式进行操作。特别是对于DTO,通常最好是简单的。