2

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.

5
  • 1 solution: @RequestParam(value = "time_target") String[] timeTargeting this work for you ? Commented Jun 14, 2017 at 16:31
  • 1
    This controller is going to get really messy. You could just send the whole JSON string in one POST parameter. Then in your backend, you use a simple JSON library to parse the string and get the data out of it. Commented Jun 14, 2017 at 16:37
  • 1
    I even doubt it works. You are posting JSON not request parameters (afaik). Just send the JSON as a body, create an object and map all parameters to that object (jackson will do that for you). Commented Jun 14, 2017 at 17:15
  • M. Deinum or @mumpitz can one of you post an answer with an example? I tried that, but really got confused from irrelevant examples I found online... Commented Jun 14, 2017 at 17:18
  • You can use a converter like Jackson to transform from string to Java object Commented Jun 14, 2017 at 17:22

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Worked just fine. However, I had to change the ajax call a bit to include Content-Type: "application/json"
I arrived here while searching for different ways to solve a question I just posted here. This solution looked like it would work for me, but it didn't. The objects the save method receives have variables that are Strings containing URLs to other objects in the database. Any controller method I implement fail to convert these URLs. This conversion works in extended default repository methods, but the front end can't reach custom save repository methods.

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.