title: How to make AngularJs http.put() and Spring controller work together (no more status 400 errors)?
body: <p>I am learning AngularJs with Spring.  I am converting an existing Spring MVC server to work with Angular-provided JSON.</p>
  
  <p>Doing the GET was rather easy, cribbing from tutorial code. Doing a PUT is proving challenging.  I mostly get status 400 (syntactically incorrect).  Rather than thrash about I've decided to ask for advice.</p>
  
  <p>Here is part my Spring controller:</p>
  
  <pre><code>@RequestMapping(value = "/json/{id}", method = RequestMethod.GET)
  public @ResponseBody User getJEdit(@PathVariable("id") Long id) {
      [snip]
      User user = userService.get(id);
      [snip]
      return user;
  }
  
  @RequestMapping(value = "/json/{id}", method = RequestMethod.PUT)
  public @ResponseBody User putJEdit(@RequestBody User userAttribute, @PathVariable("id") Long id) {
      [snip]
  }
  </code></pre>
  
  <p>Here is the AngularJs controller code:</p>
  
  <pre><code>angular.module("myapp", [])
    .controller("MyController", function($scope, $http) {
      $scope.myDataGet = {};
      $scope.myDataGet.doClickGet = function(item, event) {
        var responsePromise = $http.get("/exchangeboard/admin/user/json/1");
        responsePromise.success(function(data, status, headers, config) {
          $scope.myDataGet.fromServer = data;
        });
        responsePromise.error(function(data, status, headers, config) {
          alert("AJAX failed!");
        });
      };
      $scope.myDataPut = {};
      $scope.myDataPut.doClickPut = function(item, event) {
        var responsePromise = $http.put("/exchangeboard/admin/user/json/1", 
          $scope.myDataGet.fromServer, {contentType: "application/x-www-form-urlencoded"});
        responsePromise.success(function(data, status, headers, config) {
          $scope.myDataPut.fromServer = data;
        });
        responsePromise.error(function(data, status, headers, config) {
          alert("AJAX failed!");
        });
      }
    });
  </code></pre>
  
  <p>The response from the GET works just fine (one line, broken for display):</p>
  
  <pre><code>{"id":1,"orgId":23,"name":"admin","password":"XXX",
   "role":"ROLE_ADMIN","fullName":"Jerome","phone":"",
   "email":"jerome@myemail.com","preferredContactMethod":"E",
   "inactiveDate":null,"orgName":"Org 2 receiver","donor":false,
   "adminRole":true,"inactiveDateString":""}
  </code></pre>
  
  <p>I turn around and send this right back to the server.  I get this error:</p>
  
  <pre><code>&lt;body&gt;
    &lt;h1&gt;HTTP Status 400 - &lt;/h1&gt;
    &lt;HR size="1" noshade="noshade"&gt;
    &lt;p&gt;&lt;b&gt;type&lt;/b&gt; Status report&lt;/p&gt;
    &lt;p&gt;&lt;b&gt;message&lt;/b&gt; &lt;u&gt;&lt;/u&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;description&lt;/b&gt; &lt;u&gt;The request sent by the client was syntactically incorrect.&lt;/u&gt;&lt;/p&gt;
    &lt;HR size="1" noshade="noshade"&gt;
    &lt;h3&gt;VMware vFabric tc Runtime 2.9.5.SR1/7.0.50.C.RELEASE&lt;/h3&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>The server code putJEdit() isn't contacted -- no breakpoints are hit.</p>
  
  <p>I think the answer is to have a correct content type, but which?</p>
  
  <p>A second question:  Suppose the server wants to validate things.  I'm passing about a User object.  I'm thinking I should be passing around something with a wrapper, so I can include errors and messages.  Must this be home-grown?  Or will something on the Spring side like ResponseEntity serve me?</p>
  
  <p>A third question: Suppose I'm supposed to use something like User, and not a wrapper. What syntax do I use for sending a list or array of User objects?</p>
  
  <p>Thanks much, Jerome.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Sorry about changing things up so much.  I found another Spring MVC package I used for JSON communication and changed my problem to use ResponseEntity.  This gives me a place for custom statuses and messages.  I still don't have success, though.
  My Java controller section:</p>
  
  <pre><code>@RequestMapping(value = "/json/{id}", method = RequestMethod.GET, produces="application/json")
  @ResponseBody
  public ResponseEntity&lt;User&gt; getJEdit(@PathVariable("id") Long id) {
      [snip]
      return new ResponseEntity&lt;User&gt;(user, HttpStatus.OK);
  }
  
  @RequestMapping(value = "/json/{id}", method = RequestMethod.PUT, consumes = "application/json", produces="application/json")
  @ResponseBody
  public ResponseEntity&lt;User&gt; putJEdit(@RequestBody User userAttribute, @PathVariable("id") Long id) {
      [snip]
      return new ResponseEntity&lt;User&gt;(user, HttpStatus.OK);
  }
  </code></pre>
  
  <p>My AngularJs module:</p>
  
  <pre><code>angular.module("myapp", []).controller("MyController", function($scope, $http) {
    $http.defaults.useXDomain = true;
    $scope.myDataGet = {};
    $scope.myDataGet.doClickGet = function(item, event) {
      var responsePromise = $http.get("/exchangeboard/admin/user/json/1");
      responsePromise.success(function(data, status, headers, config) {
        $scope.myDataGet.fromServer = data;
      });
      responsePromise.error(function(data, status, headers, config) {
        alert("AJAX failed!");
      });
    };
    $scope.myDataPut = {};
    $scope.myDataPut.doClickPut = function(item, event) {
      var responsePromise = $http.put("/exchangeboard/admin/user/json/1", $scope.myDataGet.fromServers, {headers: {'Content-Type': 'application/json'}});
      responsePromise.success(function(data, status, headers, config) {
        $scope.myDataPut.fromServer = data;
      });
      responsePromise.error(function(data, status, headers, config) {
        alert("AJAX failed!");
      });
    };
  });
  </code></pre>
  
  <p>The GET always succeeds.  This means my basic Spring communication is taking place OK.  I consistently get "Request method 'PUT' not supported -- The specified HTTP method is not allowed for the requested resource."</p>
  
  <p>In my server I do have a mapping:</p>
  
  <pre><code>INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
  - Mapped "{[/admin/user/json/{id}],methods=[PUT],params=[],headers=[],consumes=[application/json],produces=[application/json],custom=[]}" 
  onto public org.springframework.http.ResponseEntity&lt;mystuff.domain.User&gt; mystuff.controller.UserController.putJEdit(mystuff.domain.User,java.lang.Long)
  </code></pre>
  
  <p>So I don't know what I'm doing wrong. If I change everything to use POST instead of PUT I still get the same 405.
  Jerome.</p>