рдкрд░рд┐рдЪрдп
рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдореБрдЭреЗ рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рд╕реЗ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ рдФрд░ рдЬрд╣рд╛рдВ рдХреЛрдИ рдирд╣реАрдВ рд╣реИрдВред рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЗрд╕ рддрдереНрдп рд╕реЗ рдЬрдЯрд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рд╕реНрдкреНрд░рд┐рдВрдЧ рдПрдорд╡реАрд╕реА рдХреА рдорд╛рдирдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдиреЗ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреАред рдореБрдЭреЗ рдереЛрдбрд╝реА рдЧрд╣рд░реА рдЦреБрджрд╛рдИ рдХрд░рдиреА рдереАред рдХреМрди рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ - рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рд╣рдо рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рдпрд╣рд╛рдБ рдПрдХ рдЫреЛрдЯрд╛ рдкрд░реАрдХреНрд╖рдг рд╣реИ рдЬреЛ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред
TestControllerTest.java@SpringJUnitWebConfig(WebConfig.class) class TestControllerTest { @Autowired WebApplicationContext webApplicationContext; @Test void testHandleRequestWithoutParams() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); mockMvc.perform(MockMvcRequestBuilders.get("/test")) .andExpect(status().isOk()) .andExpect(result -> assertEquals(TestController.HANDLE_REQUEST_WITHOUT_PARAMS, result.getResponse().getContentAsString())); } @Test void testHandleRequestWithParams() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); mockMvc.perform(MockMvcRequestBuilders .get("/test") .param("someparam", "somevalue")) .andExpect(status().isOk()) .andExpect(result -> assertEquals(TestController.HANDLE_REQUEST_WITH_PARAMS, result.getResponse().getContentAsString())); } }
рд╣рдореЗрдВ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдЕрдкрдиреЗ рдЖрдк рд╣рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛
TestController.java @Controller @RequestMapping("/test") public class TestController { public static final String HANDLE_REQUEST_WITH_PARAMS = "handleRequestWithParams"; public static final String HANDLE_REQUEST_WITHOUT_PARAMS = "handleRequestWithoutParams"; @GetMapping @ResponseBody public String handleRequestWithParams(SearchQuery query) { return HANDLE_REQUEST_WITH_PARAMS; } @GetMapping @ResponseBody public String handleRequestWithoutParams() { return HANDLE_REQUEST_WITHOUT_PARAMS; } }
рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕реНрдкреНрд░рд┐рдВрдЧ рдЕрдкреЗрдХреНрд╖рд╛ рдХреЗ рдЕрдиреБрд░реВрдк рдирд╣реАрдВ рдерд╛, рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдерд╛:
java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'getTestController' method public java.lang.String ru.pchurzin.spring.customannotations.TestController.handleRequestWithoutParams() to {GET /test}: There is already 'getTestController' bean method public java.lang.String ru.pchurzin.spring.customannotations.TestController.handleRequestWithParams(ru.pchurzin.spring.customannotations.SearchQuery) mapped.`
рд╣рд╛рд░ рдордд рдорд╛рдиреЛ
@RequestMapping(params = "some condition")
рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрди рддрд░реАрдХреЛрдВ рдХреА рдореИрдкрд┐рдВрдЧ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рд╕реНрдкреНрд░рд┐рдВрдЧ 5.1.8 рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХрд┐рд╕реА рднреА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рд╢рд░реНрдд рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред рдЖрдк рдпрд╛ рддреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рди рддреЛ рдПрдХ рдФрд░ рди рд╣реА рджреВрд╕рд░рд╛ рдЙрдкрдпреБрдХреНрдд рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдХреБрдЫ рдРрд╕рд╛ рд▓рд┐рдЦрдирд╛ @RequestMapping(params = "*")
рдпрд╣ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдХреБрдЫ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП рдпрд╛ @RequestMapping (params = "! *!") `рдпрд╣ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдХреНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП! рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИред
рдФрд░ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдХреНрдпрд╛ рд╣реИ?
рдкреНрд░рд▓реЗрдЦрди рдзреВрдореНрд░рдкрд╛рди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЕрдиреБрднрд╛рдЧ CustomAnnotations рдкрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ:
Spring MVC also supports custom request-mapping attributes with custom request-matching logic.
рдпрд╣ рдореЗрд░рд╛ рдПрдиреЛрдЯреЗрд╢рди рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рдиреЗ рдореБрдЭреЗ рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЙрдкрд▓рдмреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╢рд░реНрддреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред
рд▓рдХреНрд╖реНрдп
рдореИрдВ рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ @NoRequestParams
рдПрдиреЛрдЯреЗрд╢рди рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬреЛ рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рдзрд┐ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреА рд╣реИред
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NoRequestParams { }
рд╣рдорд╛рд░реЗ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдирд┐рдпрдВрддреНрд░рдХ:
TestContoller.java @Controller @RequestMapping("/test") public class TestController { public static final String HANDLE_REQUEST_WITH_PARAMS = "handleRequestWithParams"; public static final String HANDLE_REQUEST_WITHOUT_PARAMS = "handleRequestWithoutParams"; @GetMapping @ResponseBody public String handleRequestWithParams(SearchQuery query) { return HANDLE_REQUEST_WITH_PARAMS; } @GetMapping @ResponseBody @NoRequestParams
рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ
@EnableWebMvc рдПрдиреЛрдЯреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рд╕рдХреНрд░рд┐рдп рдорд╛рдирдХ рд╕реНрдкреНрд░рд┐рдВрдЧ-MVC рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди, WebMvcConfigurationSupport рд╡рд░реНрдЧ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИред рдпрд╣ RequestMappingHandlerMapping рд╡рд░реНрдЧ рдХреА рдПрдХ рд╕реЗрдо рдХреЛ рддреБрд░рдВрдд рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ RequestMappingInfo рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореИрдкрд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рд╡рд┐рдзрд┐ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рдореИрдкрд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рд╢рд░реНрддреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХреА рдЬрд╛рддреА рд╣реИ - рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдЬреЛ RequestCondition рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ ред рд╡рд╕рдВрдд рдореЗрдВ 6 рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ:
рдЗрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ RequestCondition рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдорд╛рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЖрдк рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд╕реАрдзреЗ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдПрдХ рд╕рд╛рд░ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
AbstractRequestCondition ред
NoRequestParamsCondition.java public class NoRequestParamsCondition extends AbstractRequestCondition<NoRequestParamsCondition> { public final static NoRequestParamsCondition NO_PARAMS_CONDITION = new NoRequestParamsCondition(); @Override protected Collection<?> getContent() { return Collections.singleton("no params"); } @Override protected String getToStringInfix() { return ""; } @Override public NoRequestParamsCondition combine(NoRequestParamsCondition other) { return this; } @Override public NoRequestParamsCondition getMatchingCondition(HttpServletRequest request) { if (request.getParameterMap().isEmpty()) { return this; } return null; } @Override public int compareTo(NoRequestParamsCondition other, HttpServletRequest request) { return 0; } }
рд╣рдорд╛рд░реА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рджреЛ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЯреА рдХрдВрдмрд╛рдЗрди (рдЯреА рдЕрдиреНрдп) рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рд╢рд░реНрддреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╡рд┐рдзрд┐ рдФрд░ рд╡рд░реНрдЧ рдкрд░ рдПрдиреЛрдЯреЗрд╢рди рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдВрдпреЛрдЬрди рдХреЗ рд▓рд┐рдП рд╕рдВрдпреЛрдЬрди рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдПрдиреЛрдЯреЗрд╢рди рдПрдХ рд╕рдВрдпреЛрдЬрди рдХрд╛ рдЕрд░реНрде рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ - рдЗрд╕рд▓рд┐рдП, рд╣рдо рдмрд╕ рд╢рд░реНрдд рдХреЗ рд╣рдорд╛рд░реЗ рд╡рд░реНрддрдорд╛рди рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред
Int рддреБрд▓рдирд╛ (T рдЕрдиреНрдп, HttpServletRequest рдЕрдиреБрд░реЛрдз) рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рдирд┐рд╢реНрдЪрд┐рдд рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╛рдиреА рдпрджрд┐ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреА рдХрдИ рд╢рд░реНрддреЗрдВ рд╣реИрдВ, рддреЛ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдХреМрди рд╕рд╛ рд╕рдмрд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИред рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕реЗ, рд╣рдорд╛рд░реА рд╕реНрдерд┐рддрд┐ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╕рдВрднрд╡ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдмрд╕ 0 рдкрд░ рд▓реМрдЯрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреНред рд╣рдорд╛рд░реА рд╕рднреА рд╢рд░реНрддреЗрдВ рд╕рдорд╛рди рд╣реИрдВред
рдХрд╛рд░реНрдп рдХрд╛ рдореВрд▓ рддрд░реНрдХ рдЯреА рдкрджреНрдзрддрд┐ getMatchingCondition (HttpServletRequest рдЕрдиреБрд░реЛрдз) рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИред рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ, рд╣рдореЗрдВ рдпрд╣ рддрдп рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдорд╛рд░реА рд╕реНрдерд┐рддрд┐ рдЗрд╕ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ рдпрд╛ рдирд╣реАрдВред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╕реНрдерд┐рддрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд╛рдкрд╕ рдХрд░реЗрдВред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ null
рд▓реМрдЯреЗрдВред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдПрдХ рд╢рд░реНрдд рд╡рд╕реНрддреБ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ рдпрджрд┐ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИред
рдЕрдм рд╣рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо RequestMappingHandlerMapping рдХреЗ рдорд╛рдирдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рд▓реЗрдВрдЧреЗ
рдФрд░ getCustomMethodCondition(Method method)
рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ, рдЬреЛ рдХрд┐ рдЖрдкрдХреА рдЕрдкрдиреА рдХрд╕реНрдЯрдо рд╢рд░реНрддреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдИ рдЧрдИ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рд╢рд░реНрддреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдПрдХ getCustomTypeCondition(Class<?> handlerType)
, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдпрдВрддреНрд░рдХ рд╡рд░реНрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ:
CustomRequestMappingHandlerMapping.java public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping { @Override protected RequestCondition<?> getCustomMethodCondition(Method method) { return method.isAnnotationPresent(NoRequestParams.class) ? NO_PARAMS_CONDITION : null; } }
рддрд░реНрдХ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ - рд╣рдо рдЕрдкрдиреЗ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрджрд┐ рдпрд╣ рдореМрдЬреВрдж рд╣реИ, рддреЛ рд╣рдо рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред
рд╣рдорд╛рд░реЗ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдорд╛рдирдХ рд╕реНрдкреНрд░рд┐рдВрдЧ MVC рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВрдЧреЗ:
WebConfig.java @Configuration public class WebConfig extends WebMvcConfigurationSupport { @Override protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() { return new CustomRequestMappingHandlerMapping(); } @Bean public TestController getTestController() { return new TestController(); } }
рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рд╣рдорд╛рд░рд╛ рдПрдиреЛрдЯреЗрд╢рди рдЬреЛрдбрд╝реЗрдВ:
TestController.java @Controller @RequestMapping("/test") public class TestController { public static final String HANDLE_REQUEST_WITH_PARAMS = "handleRequestWithParams"; public static final String HANDLE_REQUEST_WITHOUT_PARAMS = "handleRequestWithoutParams"; @GetMapping @ResponseBody public String handleRequestWithParams(SearchQuery query) { return HANDLE_REQUEST_WITH_PARAMS; } @GetMapping @ResponseBody @NoRequestParams public String handleRequestWithoutParams() { return HANDLE_REQUEST_WITHOUT_PARAMS; } }
рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.851 s - in ru.pchurzin.spring.customannotations.TestControllerTest Results: Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХреЗ рддрд░реНрдХ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреА рд╢рд░реНрддреЛрдВ рдХреЗ рд╕рд╛рде рдЖ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, IP рдкрддреЗ рдкрд░ рдпрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдПрдЬреЗрдВрдЯ рдкрд░ рд╕реНрдерд┐рддрд┐рдпрд╛рдВред рд╕рд░рд▓ рдЙрдкрд╛рдп рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрдкрдиреА рдмрд╛рдЗрдХ рдХреЛ рдЕрд╕реЗрдВрдмрд▓ рдХрд░рдирд╛ рднреА рдХрднреА-рдХрднреА рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИред
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
Github рдЙрджрд╛рд╣рд░рдг рдХреЛрдб