2

I am currently struggling with an error that appears in my Chrome developer tools console

GET http://localhost:8080/movie_db/search/movie?movieTitle=Machete 415 (Unsupported Media Type)

when I try to connect to my REST service with angular JS. Since I had this issue before when I tried to access the REST service via a Simple REST plugin in Chrome, I assume that most likely a missing Content-Type header parameter is the reason for that (should be Content-Type: 'application/json').

Angular JS website says, that one could set header parameters as follows: $httpProvider.defaults.headers.get['My-Header']='value'. Regretfully this didn't have any impact and the problem still exists.

Thus I'd like to know how I can manipulate the header parameters with angular JS that are sent over to my REST service.

Right at the moment, my code looks like this:

  function SearchMovieController($scope, $resource) {

  $scope.SearchMovie = $resource('http://localhost\\:8080/movie_db/search/:action',
            {action: 'movie', movieTitle: 'Machete'},
            {get: {method: 'JSONP', headers: [{'Content-Type': 'application/json'}, {'Accept' : 'application/json'}]}});

        $scope.SearchMovie.get()
    }

Server side looks as follows (I use Spring MVC):

CONTROLLER:

@Controller
@RequestMapping( "/search/movie" )
public class SearchController { // TODO rename?

private final TheMovieDBService theMovieDBService;

@Autowired
public SearchController( TheMovieDBService theMovieDBService ) {
    this.theMovieDBService = theMovieDBService;
}


@ResponseBody
@RequestMapping( method = RequestMethod.GET, produces = "application/json", consumes = "application/json" )
public Map<String, Object> search( @RequestParam String movieTitle ) {
    Map<String, Object> response = new HashMap<String, Object>();

    try {
        TheMovieDBSearchResult searchResult =  theMovieDBService.searchMovie( movieTitle );
        response.put( "result", searchResult );
        response.put( "success", "true" );
    } catch ( EncoderException e ) {
        response.put( "success", "false" );
    }
    return response;
}
}

web.xml

 <servlet>
    <servlet-name>json</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>

    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.u6f6o.apps.movie_db.config.web.ServletConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>json</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
4
  • 1
    Since you're using JSONP I don't think content-type is relevant, unless the server is doing something weird. JSONP adds a <script> tag to the page rather than using AJAX. Commented Feb 24, 2013 at 17:29
  • 1
    Are you sure your REST service is set up correctly to give responses that work with JSONP? Commented Feb 24, 2013 at 17:33
  • Thanks for your answer @MattB., I edited the origin post and added the controller code and content of web.xml on the server side Commented Feb 24, 2013 at 19:23
  • consumes="application/json" was the problem, now it works, thanks for pointing me to the right direction! Commented Feb 24, 2013 at 19:39

1 Answer 1

2

I had to step through all of Angular's $httpBackend stuff just recently, and JSONP uses a different method to load data than the other requests.

EDIT: The code in question

So if you specify jsonp has your method it is using the following method to load your data. This will, of course, completely ignore any headers you set yourself.

in $httpBackend:

function jsonpReq(url, done) {
    // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:
    // - fetches local scripts via XHR and evals them
    // - adds and immediately removes script elements from the document
    var script = rawDocument.createElement('script'),
        doneWrapper = function() {
          rawDocument.body.removeChild(script);
          if (done) done();
        };

    script.type = 'text/javascript';
    script.src = url;

    if (msie) {
      script.onreadystatechange = function() {
        if (/loaded|complete/.test(script.readyState)) doneWrapper();
      };
    } else {
      script.onload = script.onerror = doneWrapper;
    }

    rawDocument.body.appendChild(script);
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, so there is no way to specifiy the header parameters when using jsonp?
For JSONP, you can only set headers on the server-side. The client-side will always assume that the src of the <script> tag points to a file of type text/javascript (unless you set a different type attribute, which would only be relevant if you were using VBScript or something). Remember, it's just like any other <script> tag except it's being loaded after the initial page load.

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.