0

I want to store some data from an HTML form (working with AngularJS) into my database, using Spring. For this, I'm using the @RequestBody annotation with a POJO, but I can't make it work: my POJO is instancied, but it looks like the POJO attributes are not mapped with my form values (they are all null).

Controller :

@RequestMapping(value = "/createEntities", method = RequestMethod.POST)
@ResponseBody
public List<Entity> createEntities(@RequestBody final EntityList resource, @RequestParam final String kind) {
    System.out.println("Creating entity for: " + kind);
    Preconditions.checkNotNull(resource);
    List<Entity> newEntities = new ArrayList<Entity>();
    System.out.println("Entity test = " + resource.getTest()); // Prints "Entity test = null"
    // Code below returns NullException
    //System.out.println("Entity list nb = " + resource.getEntity().size());
    if (resource.getEntities() != null && !resource.getEntities().isEmpty()) {
        System.out.println("Entity list is OK");
        for (EntityForm eForm : resource.getEntities()) {
            if (eForm.getGrant() != null) {
                Entity ent = new Entity();
                if ("RTS".equals(kind)) {
                    ent.setDept(deptService.findByAbr(DeptEnum.RTS.name()));
                } else {
                    ent.setDept(deptService.findByAbr(DeptEnum.RTB.name()));
                }
                ent.setGrant(eForm.getGrant());
                ent.setCountry(eForm.getCountry());
                ent.setName(eForm.getName());
                ent = service.create(ent);
                newEntities.add(ent);
            }
        }
    }
    return newEntities;
}

EntityList is the POJO for my form. This POJO contains a list of EntityForm (+ a string for test purpose), which is a DTO for my database entity Entity.

EntityList POJO :

public class EntityList implements Serializable {
    private static final long serialVersionUID = 6335318686899794229L;
    private List<EntityForm> entities;
    private String test;

    public EntityList() {
        super();
    }

    public EntityList(List<EntityForm> entities, String test) {
        super();
        this.entities = entities;
        this.test = test;
    }

    public List<EntityForm> getEntities() {
        return entities;
    }

    public void setEntities(List<EntityForm> entities) {
        this.entities = entities;
    }

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    } 
}

I thought the problem came from a bad mapping between my list of entities in my form and my List<EntityForm> in my POJO, that's why I added a simple String to my POJO.

AngularJS side

Service :

app.factory("Entities", function($resource) {
    return $resource("api/auth/entities", null, 
    {
        createEntities: {method:'POST', url: "api/auth/entities/createEntities", params: { kind: '@kind' }, isArray:true}
    });
})

Controller :

$scope.EntForm = {};
$scope.EntForm.entities = [];
$scope.EntForm.test = "myTest";

/* ... */

$scope.saveEnt= function() {
    console.log($scope.EntForm);
    Entities.createEntities($scope.EntForm,{kind:"RTS"},function(res) {
        var msg = 'Entities created...'; 
        ngToast.create(msg); 
        $location.path("/entities");
    });
}

In my firefox console, I see that $scope.EntForm is correctly set (I have all my entity objects with the fields set, as well as the test string defined in the controller).

Result

All this code will display :

Creating entity for: RTS
Entity test = null

What am I doing wrong ?

Carrm
  • 1,485
  • 3
  • 24
  • 45

2 Answers2

0

Have you checked out the POST payload with Firefox developer tools, is your custom createEntities method working correctly?

(Would have added this as a comment, but unfortunately I don't yet have enough reputation for that.)

jmustonen
  • 470
  • 3
  • 8
  • If you're talking about sending my own POST request without using the AngularJS `createEntities` method, I can't. There is authentication requirements (I don't know how it works exactly as I didn't code this part of the app, so I can't just turn it off), every GET/POST request fails if I try to send it through Firefox dev tools. Is there another way to test if my method works well ? – Carrm Apr 08 '15 at 09:08
  • @Chugrothas I meant checking out the actual POST request contents that your AngularJS app generates. I haven't used Firefox in a while for development purposes, and don't even have it installed on my current computer so can't check it out myself, but using the [Web Console](https://developer.mozilla.org/en-US/docs/Tools/Web_Console) you should be able to monitor for example the network requests made. Then you should be able to check that your AngularJS app correctly populates the POST contents. – jmustonen Apr 08 '15 at 10:07
  • Oh yes, sorry, I totally forgot the existence of the Network viewer in Firefox console. I checked, and the POST request sent has the correct parameters (I can see my entities and the "test" string). – Carrm Apr 08 '15 at 10:53
  • Ok, well that narrows it down a bit. :) Unfortunately I haven't been using Spring backend for a while, but perhaps it's an issue with JSON -> POJO deserialization. Perhaps [this SO question + answers](http://stackoverflow.com/questions/5930894) could help you to right direction? – jmustonen Apr 08 '15 at 11:35
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – lshettyl Apr 17 '15 at 21:15
  • 1
    @LShetty sorry to comment in this way, but did you not read the part that said *(Would have added this as a comment, but unfortunately I don't yet have enough reputation for that.)*? Yes, I would have commented below openers post, had I had enough reputation (50+) at that time to be able to do so. But yes, thank you for your criticism. – jmustonen Apr 17 '15 at 21:39
0

I had to remove the @RequestParam final String kind part from my Spring controller, and the param in AngularJS code. To get the kind, I just added $scope.EntForm.kind = "theValueIWant" in my AngularJS controller.

I don't know if it's a good way to make it work in terms of good practice, but I get the @RequestBody content now.

Carrm
  • 1,485
  • 3
  • 24
  • 45