Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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;
    }

}
}
share|improve this question
    
Please show your BuildInformation, Settings and Server code – Yannic Klem Jun 29 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. – user3758745 Jun 29 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. – user3758745 Jun 29 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. – user3758745 Jun 29 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 – Yannic Klem Jun 29 at 17:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.