Willem de Wit
Willem de Wit

Reputation: 8742

Spring MVC RequestMapping is being forwarded

I have a REST service based on Spring MVC.

This is my code:

public class SitesController {

@RequestMapping(value="/rest/sites/{id}", method=RequestMethod.GET)
@ResponseBody
public SiteDTO getSite(@PathVariable String id) {
    Integer siteId = Integer.parseInt(id);

    Site site = cms.getSite(siteId);
    SiteDTO siteResult = new SiteDTO(site);
    return siteResult;
}

@RequestMapping(value="/rest/sites", method=RequestMethod.GET)
public SitesResult getSites(@RequestParam Integer companyId) {
    Collection<Site> sites = cms.getSites(cms.getCompany(companyId));
    SitesResult sitesResult = new SitesResult(sites);
    return sitesResult;
}

}

(I skipped some code that doesn't apply to the problem)

When I go to the URL /rest/sites/1 it is returning the data that I expect, but when I go to /rest/sites?companyId=1 I get a 404 page: HTTP Status 404 - /rest/rest/sites.

The log is showing that the code in the getSitesfunction is run, but after that the log is showing the following: org.springframework.web.servlet.view.JstlView Forwarding to resource [rest/sites] in InternalResourceView 'rest/sites'

Why is it redirected instead of executed?

UPDATE

Found the problem. Because I didn't have @ResponseBody above my method, the dispatcher forwarded my request. More information here, the key thing was If the method is annotated with @ResponseBody, the return type is written to the response HTTP body. The return value will be converted to the declared method argument type using HttpMessageConverters.

Upvotes: 0

Views: 638

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280122

Because your method return type SitesResult is not one of the supported return types, Spring will add the returned object to the Model using its class name and try to render a view named by the value of your request mapping, which is why it is trying to render /rest/sites. It's not actually doing an HTTP forward, but a dispatcher forward which is what servlets do to render a view (eg. jsp).

If you want to return a specific view, return a String containing its name.

Instead

@RequestMapping(value="/rest/sites", method=RequestMethod.GET)
public SitesResult getSites(@RequestParam Integer companyId) {
    Collection<Site> sites = cms.getSites(cms.getCompany(companyId));
    SitesResult sitesResult = new SitesResult(sites);
    return sitesResult;
}

Do this

@RequestMapping(value="/rest/sites", method=RequestMethod.GET)
public String getSites(@RequestParam Integer companyId, Model model) {
    Collection<Site> sites = cms.getSites(cms.getCompany(companyId));
    SitesResult sitesResult = new SitesResult(sites);
    model.addAttribute("sitesResult", sitesResult);
    String myView = "myView";
    return myView;
}

Upvotes: 1

GJ13
GJ13

Reputation: 488

This is just a guess on my part...

Method getSites could be declared as :

public SitesResult getSites(@RequestParam("companyId") Integer companyId) {

I don't know if this would have any effect?

Or could it be that the logical view name specified does not map to a view?

Upvotes: 0

Related Questions