在我的控制器中,我的控制器方法名称等于requestmapping url。例如,/list等于方法名称list。是否有一种通用的处理程序方法可以缩短我的代码?我不想以这种方式编写每个控制器和方法。我记得.net mvc有一种配置的常用方法.Spring MVC呢?
/list
list
@Controller @RequestMapping(value = "/fooController ") public class FooController { @RequestMapping("/list") public String list(...) { ... } @RequestMapping("/save") public String save(...) { ... } @RequestMapping("/delete") public String delete(...) { ... } } @Controller @RequestMapping(value = "/basketballController ") public class BasketballController { @RequestMapping("/list") public String list(...) { ... } @RequestMapping("/save") public String save(...) { ... } @RequestMapping("/delete") public String delete(...) { ... } }
您可以使用RequestMappingHandlerMapping和覆盖默认代码
RequestMappingHandlerMapping
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo info = createRequestMappingInfo(method); if (info != null) { RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) { info = typeInfo.combine(info); } } return info; }
如您在这里看到的,它尝试从方法解析RequestMapping注释并与Controller类注释组合。
只需替换逻辑即可使用方法名称。
在这里看到类似的逻辑。代替方法名称的是安全检查。
更新:
要测试的课程。对我来说,它有效。MappingHandler我使用方法名称检查是因为存在更多的控制器,错误控制器等。对于真正的解决方案,我将在控制器上引入注释,以从逻辑中排除默认的spring控制器
public class ExtendedRequestMappingHandlerMapping extends RequestMappingHandlerMapping { protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo info; if (method.getName().startsWith("test")) { info = createRequestMappingInfoByMethodName(method); } else { info = super.getMappingForMethod(method, handlerType); } return info; } protected RequestMappingInfo createRequestMappingInfoByMethodName(Method method) { RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), RequestMapping.class); String path = requestMapping.value()[0] + "/" + method.getName(); return RequestMappingInfo .paths(path) .methods(requestMapping.method()) .params(requestMapping.params()) .headers(requestMapping.headers()) .consumes(requestMapping.consumes()) .produces(requestMapping.produces()) .mappingName(requestMapping.name()) .build(); } }
配置使用映射
@Configuration public class ExtendedWebMvcConfiguration extends WebMvcConfigurationSupport { @Override @Bean public RequestMappingHandlerMapping requestMappingHandlerMapping() { ExtendedRequestMappingHandlerMapping handlerMapping = new ExtendedRequestMappingHandlerMapping(); handlerMapping.setOrder(0); handlerMapping.setInterceptors(getInterceptors()); return handlerMapping; } @Override @Bean public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter(); adapter.setIgnoreDefaultModelOnRedirect(true); return adapter; } }
控制者
@RestController @RequestMapping("/common") public class MethodNameController { public String test() { return "test"; } public String test2() { return "test2"; } }
测试班
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class MethodNameControllerTest { @LocalServerPort private int port; @Value("${server.contextPath}") private String contextPath; private String base; @Autowired private TestRestTemplate template; @Before public void setUp() throws Exception { this.base = "http://localhost:" + port; } @Test public void testMethodNameMappingResolving() throws Exception { TestRestTemplate template = new TestRestTemplate(); String url = base + contextPath + "/common/test"; String res1 = template.getForObject(url, String.class); assertThat(res1, equalTo("test")); url += "2"; String res2 = template.getForObject(url, String.class); assertThat(res2, equalTo("test2")); } }