0

I have 2 objects List and a Settings object with many primitive values. Server also is a very complex object but passing List works fine. However, now I want to pass both of these from angularjs service to REST API and I'm having null values for both.

I didn't know how to pass both object (so it'd be great if I can do that instead). Right now, I'm wrapping it in this:

 var buildInfo = { buildInfo: { servers: $scope.$$childHead.queue, settings: self.settings } };

Originally I tried using only

var buildInfo = { servers: $scope.$$childHead.queue, settings: self.settings };

However, I get BAD REQUEST 400 error before it could get into the controller function.

for $http request, I have the following:

 return $http.put('/TPMSAdministration/build/servers/', buildInfo).then(
        function(response) {
            return response.data;
        },
        function(errResponse) {
            return $q.reject(errResponse);
        }
    );

BuildInfo.java - it has default constructor with auto-created getters/setters for these 2 fields

private Settings settings;
private Server[] servers; //original have List<Server> servers and it's working fine as single argument

Inside my REST controller I have the following:

@RequestMapping(value="/build/servers/", 
       method=RequestMethod.PUT, produces=MediaType.TEXT_PLAIN_VALUE) 
public ResponseEntity<String> build(@RequestBody BuildInformation buildInfo,
            Principal principal) {
      // I manage to not get the HTTP Bad Request 400 
      //but my buildInfo object's settings and servers are both null
}

How do I pass multiple or single wrapped object to my REST API? Thanks.

Edit: adding some more classes as requested. Note that List<Server> and Settings are passed separately to angularjs' build_service.js using $http.get. I just need to return them back to a controller after settings has been changed:

BuildInformation.java

 public class BuildInformation {

  private Settings settings;
  private List<Server> servers;

  public BuildInformation() {}

  public BuildInformation(Settings settings, List<Server> servers) {
    this.settings = settings;
    this.servers = servers;
  }

  public Settings getSettings() {
    return settings;
  }

  public void setSettings(Settings settings) {
    this.settings = settings;
  }

  public List<Server> getServers() {
    return servers;
  }

  public void setServers(List<Server> servers) {
    this.servers = servers;
  } 
}

Server.java

public class Server {

private static final byte ACTIVE = 1;

private long id;
private String name;
private String shortName;
private String webUrl;
private String type;
private String location;
private String timezone;
private String description;
private byte status;
private String version;

private AppServer appServer; //similar to server, just hold extra (String) info
private DatabaseServer databaseServer; // similar to above

public Server() {};

public Server(long id, String name, String shortName) {
    this.id = id;
    setMainInfo(name, shortName);
}

public Server(long id, String name, String shortName, AppServer appServer, DatabaseServer databaseServer) {
    this(id, name, shortName);
    setAppServer(appServer);
    setDatabaseServer(databaseServer);
}

public void setMainInfo(String name, String shortName) {
    this.name = name;
    this.shortName = shortName;
}

public void setAdditionalInfo(String type, String webUrl, String location, String timezone, 
        String description, byte active, String version) {
    this.type = type;
    this.webUrl = webUrl;
    this.location = location;
    this.timezone = timezone;
    this.description = description;
    this.status = active;
    this.version = version;
}

public long getId() {
    return id;
}

public String getName() {
    return name;
}

public String getShortName() {
    return shortName;
}

public String getServerType() {
    return type;
}

public String getWebUrl() {
    return webUrl;
}

public String getType() {
    return type;
}

public String getLocation() {
    return location;
}

public String getTimezone() {
    return timezone;
}

public String getDescription() {
    return description;
}

public boolean isActive() {
    return status == ACTIVE;
}

public byte getStatus() {
    return status;
}

public String getVersion() {
    return version;
}

public void setAppServer(AppServer appServer) {
    this.appServer = appServer;
}

public AppServer getAppServer() {
    return appServer;
}

public void setDatabaseServer(DatabaseServer databaseServer) {
    this.databaseServer = databaseServer;
}

public DatabaseServer getDatabaseServer() {
    return databaseServer;
}

}

Settings.java

public class Settings {

private final String name;
private final String operator;
private final long startTime;
private final String targetVersion;

/*
 *  localSourceCode is the source code used for the build, not the source of the 
 *  local project the user is working on. In fact that project location should 
 *  not be in the build at all or all of user's hard work will be deleted. Speaking from experience.
 */
private final String localSourceCode;

/*
 *  This is the source code location on repo server
 */
private final String remoteSourceCode;

private final String appName;

/*
 *  location of script used for the build. Build contains 2 parts: database and app, 
 *  so build scripts are different from the dbscripts directory in source code
 */
private final String scriptLocation;

/*
 *  location of the template script files
 */
private final String templateLocation;

/*
 *  installation path for the server
 */
private final String deployPath;

/*
 *  back up location for the previous installation
 */
private final String backupPath;
private final int poolSize;
private final boolean repoUpdateReq;
private final boolean onetimeScriptReq;
private final boolean javaBuildReq;
private final boolean dbBuildReq;

/*
 *  The maximum timeout in seconds to wait for the running batch to finish
 */
private final long batchTimeoutMillis;

/*
 *  The maximum runtime in minutes to run the build jobs before terminating 
 */
private final int buildTimeoutMinutes;

/*
 *  The number of retries on a procedure fails to run (due to dependency issues)
 *  Depreciated - procedures/functions are Topologically sorted instead.
 */
private final int spRetryOnFail;
private final String ant;

private final String trunkPath;
private final String branchPath;
private final String tagPath;
private final String buildPath;

private Settings(Builder builder) {
    this.name = builder.name;
    this.operator = builder.operator;
    this.startTime = builder.startTime;
    this.targetVersion = builder.targetVersion;
    this.localSourceCode = builder.localSourceCode;
    this.remoteSourceCode = builder.remoteSourceCode;
    this.appName = builder.appName;
    this.scriptLocation = builder.scriptLocation;
    this.templateLocation = builder.templateLocation;
    this.deployPath = builder.deployPath;
    this.backupPath = builder.backupPath;
    this.poolSize = builder.poolSize;
    this.repoUpdateReq = builder.repoUpdateReq;
    this.onetimeScriptReq = builder.onetimeScriptReq;
    this.javaBuildReq = builder.javaBuildReq;
    this.dbBuildReq = builder.dbBuildReq;
    this.batchTimeoutMillis = builder.batchTimeoutMillis;
    this.buildTimeoutMinutes = builder.buildTimeoutMinutes;
    this.spRetryOnFail = builder.spRetryOnFail;
    this.ant = builder.ant;
    this.trunkPath = builder.trunkPath;
    this.branchPath = builder.branchPath;
    this.tagPath = builder.tagPath;
    this.buildPath = builder.buildPath;
}

public String getScriptLocation() {
    return scriptLocation;
}

public String getTemplateLocation() {
    return templateLocation;
}

public String getDeployPath() {
    return deployPath;
}

public String getBackupPath() {
    return backupPath;
}

public int getPoolSize() {
    return poolSize;
}

public boolean isRepoUpdateReq() {
    return repoUpdateReq;
}

public boolean isOnetimeScriptReq() {
    return onetimeScriptReq;
}

public boolean isJavaBuildReq() {
    return javaBuildReq;
}

public boolean isDbBuildReq() {
    return dbBuildReq;
}

public long getBatchTimeoutMillis() {
    return batchTimeoutMillis;
}

public int getBuildTimeoutMinutes() {
    return buildTimeoutMinutes;
}

public int getSpRetryOnFail() {
    return spRetryOnFail;
}

public String getName() {
    return name;
}

public String getOperator() {
    return operator;
}

public long getStartTime() {
    return startTime;
}

public String getTargetVersion() {
    return targetVersion;
}

public String getLocalSourceCode() {
    return localSourceCode;
}

public String getRemoteSourceCode() {
    return remoteSourceCode;
}

public String getAppName() {
    return appName;
}

public String getAnt() {
    return ant;
}

public String getTrunkPath() {
    return trunkPath;
}

public String getBranchesPath() {
    return branchPath;
}

public String getTagsPath() {
    return tagPath;
}

public String getBuildsPath() {
    return buildPath;
}

public static class Builder {

    private String name;
    private String operator;
    private long startTime;
    private String targetVersion;
    private String localSourceCode;
    private String remoteSourceCode;
    private String appName = "tpar.ear";
    private String scriptLocation;
    private String templateLocation;
    private String deployPath;
    private String backupPath;
    private int poolSize = 10;
    private boolean repoUpdateReq = false;
    private boolean onetimeScriptReq = true;
    private boolean javaBuildReq = true;
    private boolean dbBuildReq = true;
    private long batchTimeoutMillis = 300000;
    private int buildTimeoutMinutes = 120;
    private int spRetryOnFail = 3;
    private String ant = "\"" + System.getenv().get("ANT_HOME") + "/bin/" + "\"" + "ant ";

    private String trunkPath;
    private String branchPath;
    private String tagPath;
    private String buildPath;

    public Builder() {};

    public Builder(Settings settings) {
        this.name = settings.name;
        this.operator = settings.operator;
        this.startTime = settings.startTime;
        this.targetVersion = settings.targetVersion;
        this.localSourceCode = settings.localSourceCode;
        this.remoteSourceCode = settings.remoteSourceCode;
        this.appName = settings.appName;
        this.scriptLocation = settings.scriptLocation;
        this.templateLocation = settings.templateLocation;
        this.deployPath = settings.deployPath;
        this.backupPath = settings.backupPath;
        this.poolSize = settings.poolSize;
        this.repoUpdateReq = settings.repoUpdateReq;
        this.onetimeScriptReq = settings.onetimeScriptReq;
        this.javaBuildReq = settings.javaBuildReq;
        this.dbBuildReq = settings.dbBuildReq;
        this.batchTimeoutMillis = settings.batchTimeoutMillis;
        this.buildTimeoutMinutes = settings.buildTimeoutMinutes;
        this.spRetryOnFail = settings.spRetryOnFail;
        this.ant = settings.ant;
        this.trunkPath = settings.trunkPath;
        this.branchPath = settings.branchPath;
        this.tagPath = settings.tagPath;
        this.buildPath = settings.buildPath;
    }

    public Settings build() {
        return new Settings(this);
    }

    public Builder name(String name) {
        this.name = name;
        return this;
    }

    public Builder operator(String operator) {
        this.operator = operator;
        return this;
    }

    public Builder startTime(long startTime) {
        this.startTime = startTime;
        return this;
    }

    public Builder targetVersion(String targetVersion) {
        this.targetVersion = targetVersion;
        return this;
    }

    public Builder localSourceCode(String localSourceCode) {
        this.localSourceCode = localSourceCode;
        return this;
    }

    public Builder remoteSourceCode(String remoteSourceCode) {
        this.remoteSourceCode = remoteSourceCode;
        return this;
    }

    public Builder scriptLocation(String scriptLocation) {
        this.scriptLocation = scriptLocation;
        return this;
    }

    public Builder appName(String appName) {
        this.appName = appName;
        return this;
    }

    public Builder templateLocation(String templateLocation) {
        this.templateLocation = templateLocation;
        return this;
    }

    public Builder deployPath(String deployPath) {
        this.deployPath = deployPath;
        return this;
    }

    public Builder backupPath(String backupPath) {
        this.backupPath = backupPath;
        return this;
    }

    public Builder poolSize(int poolSize) {
        this.poolSize = poolSize;
        return this;
    }

    public Builder repoUpdateReq(boolean repoUpdateReq) {
        this.repoUpdateReq = repoUpdateReq;
        return this;
    }

    public Builder onetimeScriptReq(boolean onetimeScriptReq) {
        this.onetimeScriptReq = onetimeScriptReq;
        return this;
    }

    public Builder javaBuildReq(boolean javaBuildReq) {
        this.javaBuildReq = javaBuildReq;
        return this;
    }

    public Builder dbBuildReq(boolean dbBuildReq) {
        this.dbBuildReq = dbBuildReq;
        return this;
    }

    public Builder batchTimeoutMillis(long batchTimeoutMillis) {
        this.batchTimeoutMillis = batchTimeoutMillis;
        return this;
    }

    public Builder buildTimeoutMinutes(int buildTimeoutMinutes) {
        this.buildTimeoutMinutes = buildTimeoutMinutes;
        return this;
    }

    public Builder spRetryOnFail(int spRetryOnFail) {
        this.spRetryOnFail = spRetryOnFail;
        return this;
    }

    public Builder ant(String ant) {
        this.ant = ant;
        return this;
    }

    public Builder trunkPath(String trunkPath) {
        this.trunkPath = trunkPath;
        return this;
    }

    public Builder branchPath(String branchPath) {
        this.branchPath = branchPath;
        return this;
    }

    public Builder tagPath(String tagPath) {
        this.tagPath = tagPath;
        return this;
    }

    public Builder buildPath(String buildPath) {
        this.buildPath = buildPath;
        return this;
    }

}
}
10
  • Please show your BuildInformation, Settings and Server code Commented Jun 29, 2016 at 8:10
  • Hi, thank you very much for taking a look. I've added the code as requested. Please note that List<Server> and Settings are passed separately to angularjs' build_service.js using $http.get. I just need to return them back to a controller after settings has been changed. Commented Jun 29, 2016 at 16:44
  • Sorry one more thing. instead of List<Server> inside BuildInformation, it's' Server[]. I undo everything because Server[] wasn't working either. Commented Jun 29, 2016 at 16:49
  • Hey I think I got it. Using var buildInfo = { servers: $scope.$$childHead.queue, settings: self.settings }; today gave an error that I wasn't seeing yesterday: Could not read document: No suitable constructor found for type [simple type, class com.tpms.build.model.Settings]. Settings used the Builder Design Pattern and doesn't have a constructor. I'm going to remove the Builder and make it into a normal class. I hope this fix everything. Please let me know if you find something else wrong with it though. Thanks, you have my appreciation. Commented Jun 29, 2016 at 17:00
  • you need setters for all fields that should be deserialized by jackson. So since your settings and server objects doesnt have these setters, all values are null Commented Jun 29, 2016 at 17:09

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.