Java 如何使用@RequestMapping优化SpringMVC控制器中的代码?

Java 如何使用@RequestMapping优化SpringMVC控制器中的代码?,java,spring,spring-mvc,spring-boot,Java,Spring,Spring Mvc,Spring Boot,在我的控制器中,我的控制器方法名称等于requestmapping url。例如,/list等于方法名称list。是否有一个通用的处理程序方法来缩短我的代码?我不想以这种方式编写每个控制器和方法。我记得.net mvc有一种comom方式来配置它。Spring mvc呢 @Controller @RequestMapping(value = "/fooController ") public class FooController { @RequestMapping("/list")

在我的控制器中,我的控制器方法名称等于requestmapping url。例如,
/list
等于方法名称
list
。是否有一个通用的处理程序方法来缩短我的代码?我不想以这种方式编写每个控制器和方法。我记得.net mvc有一种comom方式来配置它。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(...) { ... }
}

两个控制器的抽象基类是否都适用于您

public abstract class BaseController<T> {
     @RequestMapping("/list") public String list(...) { ... }
     @RequestMapping("/save") public String save(...) { ... }
     @RequestMapping("/delete") public String delete(...) { ... }
}

@Controller
@RequestMapping(value = "/fooController ")
public class FooController extends BaseController<Foo> {      
}

@Controller
@RequestMapping(value = "/basketballController ")
public class BasketballController extends BaseController<Basketball> {
}
公共抽象类BaseController{
@RequestMapping(“/list”)公共字符串列表(…){…}
@请求映射(“/save”)公共字符串保存(…){…}
@RequestMapping(“/delete”)公共字符串删除(…){…}
}
@控制器
@请求映射(value=“/fooController”)
公共类FooController扩展BaseController{
}
@控制器
@请求映射(value=“/basketballController”)
公共类BasketballController扩展BaseController{
}

您可以使用
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;
}
控制器

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

}

您可以扩展到
AbstractControllerUrlHandlerMapping
,覆盖该方法并在web.xml中添加bean

  <beans:bean id="myControllerClassNameHandlerMapping" class="com.qiyongkang.sys.controller.MyControllerClassNameHandlerMapping">
  <beans:property name="interceptors">
      <beans:array>
          <beans:bean id="sysLogInterceptor" class="com.qiyongkang.sys.interceptor.SysLogInterceptor"></beans:bean>
      </beans:array>
  </beans:property>
  <beans:property name="caseSensitive" value="true" />
  <beans:property name="frameworkPackagePrefixs" value="com.qiyongkang." />
  <beans:property name="actionPackageSuffixs" value=".ctrl,.controller" />
  <beans:property name="actionClassSuffixs" value="Ctrl,Controller" />


这是一个。

它可以工作一点,但它不是我想要的方式。如果我有一些BaseController中没有的方法,我必须以原始方式编写。我不太明白你所说的“一些方法”是什么意思。如果它不是一个常用的方法,您想如何优化它?某些方法意味着在某些控制器中它可能有导出方法,而在另一个控制器中它可能根据实际业务有其他方法。我看不到在抽象类中灵活定制其工作有任何问题。是的,如果basecontroller中的常用方法和single controller中的特殊方法可以使用相同的处理程序,则效果会更好。如果海报没有反映,您是否可以编辑您的答案以显示一些方法名称逻辑?createRequestMappingInfo方法在哪里?答案已更新。最好检查RequestMappingHandlerMapping的源代码class@StanislavL,它在createRequestMappingInfoByMethodName()中调用错误。对于类型AnnotatedDelementUtilsi use spring core 4.3.8.RELEASE,未定义FindMergeAnnotation(类,类)方法。我猜是版本的问题。我认为您只需获取该方法的类并从该类获取RequestMapping(实际上是控制器的RequestMapping注释)
@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"));
    }

}
  <beans:bean id="myControllerClassNameHandlerMapping" class="com.qiyongkang.sys.controller.MyControllerClassNameHandlerMapping">
  <beans:property name="interceptors">
      <beans:array>
          <beans:bean id="sysLogInterceptor" class="com.qiyongkang.sys.interceptor.SysLogInterceptor"></beans:bean>
      </beans:array>
  </beans:property>
  <beans:property name="caseSensitive" value="true" />
  <beans:property name="frameworkPackagePrefixs" value="com.qiyongkang." />
  <beans:property name="actionPackageSuffixs" value=".ctrl,.controller" />
  <beans:property name="actionClassSuffixs" value="Ctrl,Controller" />