mariobgr
mariobgr

Reputation: 2201

JSON object and Spring @RequestParam

I'm manipulating the following JSON object in my website frontend

<script>
window.campaign = {
    name: "test",
    budget: 20.00,
    type: 0,
    dynamic: false,
    geo_target: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],
    time_target: {
        monday: ["00","00","00","00",1],
        tuesday: ["00","00","00","00",1],
        wednesday: ["00","00","00","00",1],
        thursday: ["00","00","00","00",1],
        friday: ["00","00","00","00",1],
        saturday: ["00","00","00","00",1],
        sunday: ["00","00","00","00",1]
    },

    setName: function(val) {
        this.name = val;
    },

    //some more setters go here
}
</script>

Then I send it to my Spring application using AJAX

$.ajax({ type: "POST", url: submit_url, data: JSON.stringify(window.campaign) })
.done(function() { alert( "success" ); })
.fail(function() { alert( "error" ); });

Now the problem is mapping all the variables accordingly in my @Controller

....
@RequestParam(value = "name", required = false, defaultValue = "") String name,
@RequestParam(value = "budget", required = false, defaultValue = "0") BigDecimal budget,
@RequestParam(value = "type", required = false, defaultValue = "0") int type,
@RequestParam(value = "dynamic", required = false, defaultValue = "false") boolean dynamic,
@RequestParam(value = "geo_target", required = false, defaultValue = "") int[] geoTargeting,
....

This all works fine, but I have no idea how to map the time_target

I tried creating a new Model and mapping it using @RequestBody

....
@RequestParam(value = "name", required = false, defaultValue = "") String name,
....
@RequestParam(value = "geo_target", required = false, defaultValue = "") int[] geoTargeting,    
@RequestBody TimeTarget timeTargeting
....

with no success. I used http://www.jsonschema2pojo.org to create a Class for the whole object I'm sending, but no success whatsoever (just FYI, it created two classes, one for timeTargeting and one for everything else).

I'm getting really desperate. Help, please :) If the code provided is not enough, I can update with more.

Upvotes: 2

Views: 18070

Answers (1)

Danylo Zatorsky
Danylo Zatorsky

Reputation: 6094

You should create a wrapper around your JSON structure in Java and pass it through to the controller as a @RequestBody. Here is what worked for me:

public class CampaignDTO {
    private String name;
    private BigDecimal budget;
    private Integer type;
    private Boolean dynamic;

    @JsonProperty("geo_target")
    private List<Integer> geoTarget;

    @JsonProperty("time_target")
    private TimeTarget timeTarget;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getBudget() {
        return budget;
    }

    public void setBudget(BigDecimal budget) {
        this.budget = budget;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Boolean getDynamic() {
        return dynamic;
    }

    public void setDynamic(Boolean dynamic) {
        this.dynamic = dynamic;
    }

    public List<Integer> getGeoTarget() {
        return geoTarget;
    }

    public void setGeoTarget(List<Integer> geoTarget) {
        this.geoTarget = geoTarget;
    }

    public TimeTarget getTimeTarget() {
        return timeTarget;
    }

    public void setTimeTarget(TimeTarget timeTarget) {
        this.timeTarget = timeTarget;
    }
}

Another DTO which is included in the CampainDTO:

public class TimeTarget {
    private List<String> monday;
    private List<String> tuesday;
    private List<String> wednesday;
    private List<String> thursday;
    private List<String> friday;
    private List<String> sunday;

    public List<String> getMonday() {
        return monday;
    }

    public void setMonday(List<String> monday) {
        this.monday = monday;
    }

    public List<String> getTuesday() {
        return tuesday;
    }

    public void setTuesday(List<String> tuesday) {
        this.tuesday = tuesday;
    }

    public List<String> getWednesday() {
        return wednesday;
    }

    public void setWednesday(List<String> wednesday) {
        this.wednesday = wednesday;
    }

    public List<String> getThursday() {
        return thursday;
    }

    public void setThursday(List<String> thursday) {
        this.thursday = thursday;
    }

    public List<String> getFriday() {
        return friday;
    }

    public void setFriday(List<String> friday) {
        this.friday = friday;
    }

    public List<String> getSunday() {
        return sunday;
    }

    public void setSunday(List<String> sunday) {
        this.sunday = sunday;
    }
}

And the last part is your controller. Note that here it works as an echo - it returns exactly what you posted. That's why I added @ResponseBody here.

@Controller
public class CampainController {

    @RequestMapping(name = "/test", method = RequestMethod.POST)
    @ResponseBody
    public CampaignDTO test(@RequestBody CampaignDTO campaignDTO) {
        return campaignDTO;
    }
}

After you post your request to http://localhost:8080/test it should work properly.

Upvotes: 2

Related Questions