naXa stands with Ukraine
naXa stands with Ukraine

Reputation: 37926

Request handler is executed, but response status is always 404

I have a simple web controller that handles requests to GET /base/{userId}/test/{userId} (e.g. GET /base/1/test/2) and returns an object that should be converted to JSON later.

@Controller
@RequestMapping("/base/{userId}")
public class TestController {

    @Autowired
    TestService testService;

    @GetMapping("/test/{testId}")
    Response<TestDto> getTest(@PathVariable("userId") Long userId, @PathVariable("testId") Long testId) {
        return Response.ok(testService.get(userId));
    }

}

But whenever I call it I get "404 - Not found" in response. I've debugged my code and I'm sure that the TestService service and the Response#ok() method are working fine.

Then I've debugged Spring Framework sources and found that for some unknown bizarre reason the Spring's internal filter chain is executed twice and request URI is messed up in the second execution (URI is duplicated). E.g., on the first execution I have request.servletPath = "/base/1/test/2", on the subsequent execution I have request.servletPath = "/base/1/base/1/test/2" (* see notes below). Then the mentioned 404 error is returned, cause apparently I don't have mapping for /base/1/base/1/test/2 in my application.

What's wrong and how can I fix it?


* request is of type ApplicationHttpRequest here.
Other messed up request properties are: strippedServletPath, requestDispatcherPath, requestUri. I don't put them in the answer body for a sake of brevity

Upvotes: 0

Views: 386

Answers (1)

naXa stands with Ukraine
naXa stands with Ukraine

Reputation: 37926

You simply forgot to put @ResponseBody annotation on your getTest() method.

Annotation that indicates a method return value should be bound to the web response body.

This code should work:

@GetMapping("/test/{testId}")
@ResponseBody
public Response<TestDto> getTest(@PathVariable("userId") Long userId, @PathVariable("testId") Long testId) {
    return Response.ok(testService.get(userId));
}

Upvotes: 1

Related Questions