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;
}
}
}
List<Server>
andSettings
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. – user3758745 Jun 29 at 16:44List<Server>
inside BuildInformation, it's'Server[]
. I undo everything becauseServer[]
wasn't working either. – user3758745 Jun 29 at 16:49var 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. – user3758745 Jun 29 at 17:00