java - 如何使用@RequestMapping 在 Spring MVC Controller 中优化我的代码?

标签 java spring spring-mvc spring-boot

在我的 Controller 中,我的 Controller 方法名称等于请求映射 url。例如,/list 等于方法名称 list。是否有通用的处理程序方法来缩短我的代码?我不想以这种方式编写每个 Controller 和方法。我记得 .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 类注释结合。

只需将逻辑替换为使用方法名即可。

参见 here类似的逻辑。使用安全检查而不是方法名称。

更新:

要测试的类。对我来说它有效。 MappingHandler 我使用方法名称检查,因为有更多的 Controller 、错误 Controller 等。对于真正的解决方案,我会在 Controller 上引入一个注释,以从逻辑中排除默认的 spring Controller

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;
    }

}

Controller

@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"));
    }

}

关于java - 如何使用@RequestMapping 在 Spring MVC Controller 中优化我的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43982249/

相关文章:

java - 使用 Spring Rest 模板调用 Rest 服务

spring-mvc - 带下划线的 Spring 引导路径变量不调用 Controller

java - java中如何获取图片大小

java - JPA Criteria Builder 中的 If/Case 语句

java - 无法使用 REST 架构和 Angular JS 在 Spring Boot 中映射新 url,并且发布请求未接收对象字段值

java - 用于集成测试的 AWS S3 Java 嵌入式模拟

java - 隐藏敏感信息作为回应

java - Netbeans 失败 - 应用程序已存在于路径/

java - 在抽象类中 Autowiring 不同的bean

spring - 对 Spring GenericBeanDefinition 的引用