如何使用@RequestMapping在Spring MVC Controller中优化我的代码?
在我的控制器中,我的控制器方法名称等于请求映射URL。例如, /list
等于方法名称list
。 是否有一个通用的处理程序方法来缩短我的代码?我不想以这种方式编写每个控制器和方法。我记得.net mvc有一个简单的方法来配置它。关于Spring MVC怎么样?
@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
并覆盖默认代码
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我使用方法名称检查,因为有更多的控制器,错误控制器等。对于真正的解决方案,我将在控制器上引入一个注释,以从逻辑中排除默认的弹簧控制器
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"; } }
考试class
@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")); } }
两个控制器的抽象基类是否适合您?
public abstract class BaseController { @RequestMapping("/list") public String list(...) { ... } @RequestMapping("/save") public String save(...) { ... } @RequestMapping("/delete") public String delete(...) { ... } } @Controller @RequestMapping(value = "/fooController ") public class FooController extends BaseController { } @Controller @RequestMapping(value = "/basketballController ") public class BasketballController extends BaseController { }
您可以扩展到AbstractControllerUrlHandlerMapping
并覆盖该方法并在web.xml中添加bean。
这是一个例子 。