Skip to content

DispatcherServlet gets wrong request handler depending on Accept header #31458

@SeongEon-Jo

Description

@SeongEon-Jo

Affects: springframework version 5.3.29

I developed Controller class like below.

@RestController
@RequiredArgsConstructor
public class OrderController {

    @GetMapping(value = "/orders/{no}", produces = "application/json")
    public Long getOrder(@PathVariable Long no) {
        return no;
    }

    @GetMapping(value = "/orders/title", produces = "text/plain")
    public String getOrderTitle(@RequestParam(name = "order_no") List<Long> orderNoList) {
        return "title";
    }
}

Based on this, I ran test like below.

@Test
    void test() throws Exception {
        ResultActions perform = mockMvc.perform(get("/orders/title")
                .accept("application/json")
                .param("order_no", "1, 2, 3"));

        perform.andExpect(status().isNotAcceptable());
    }

It failed because actual status was 400 bad request.

I also found a log and it said like below.

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /orders/title
       Parameters = {order_no=[1, 2, 3]}
          Headers = [Accept:"application/json"]
             Body = null
    Session Attrs = {}

Handler:
             Type = com.example.demo.controller.OrderController
           Method = com.example.demo.controller.OrderController#getOrder(Long) // note this

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.web.method.annotation.MethodArgumentTypeMismatchException

...

java.lang.AssertionError: Status expected:<406> but was:<400>
Expected :406
Actual   :400

It looks weird because GET /orders/title should invoke OrderController#getOrderTitle().

Servlet seems to fail to distinguish variable argument like {no} from static argument like title in URI.

Please note that it has something to do with Accept header (relevant to produces parameter in @GetMapping) because it gets the right handler if I remove all produces parameter in @GetMapping.

Is is a bug? or am I using it in a wrong way?

Metadata

Metadata

Assignees

No one assigned

    Labels

    for: stackoverflowA question that's better suited to stackoverflow.comstatus: invalidAn issue that we don't feel is valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions