복붙노트

[SPRING] @RequestMapping을 사용하여 Spring MVC 컨트롤러에서 코드를 최적화하는 방법은 무엇입니까?

SPRING

@RequestMapping을 사용하여 Spring MVC 컨트롤러에서 코드를 최적화하는 방법은 무엇입니까?

내 컨트롤러에서 내 컨트롤러 메서드 이름은 requestmapping url과 동일합니다. 예를 들어, / list는 메서드 이름 목록과 같습니다. 내 코드를 단축하는 공통 처리기 메서드가 있습니까? 이러한 방법으로 모든 컨트롤러와 메서드를 작성하고 싶지 않습니다 .net mvc가 설정하는 comom 방법이 있다는 것을 기억하고 있습니다. 스프링 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(...) { ... }
}

해결법

  1. ==============================

    1.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 훨씬 더 많은 컨트롤러, 에러 컨트롤러 등이 있기 때문에 메서드 이름 검사를 사용합니다. 실제 솔루션을 위해 컨트롤러에서 기본 스프링 컨트롤러를 논리에서 제외시키기위한 주석을 도입했습니다

    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"));
        }
    
    }
    
  2. ==============================

    2.두 컨트롤러의 추상 기본 클래스가 당신을 위해 작동합니까?

    두 컨트롤러의 추상 기본 클래스가 당신을 위해 작동합니까?

    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> {
    }
    
  3. ==============================

    3.AbstractControllerUrlHandlerMapping으로 확장하고 메소드를 재정의하고 web.xml에 Bean을 추가 할 수있다.

    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" />
    

    다음은 그 예입니다.

  4. from https://stackoverflow.com/questions/43982249/how-to-optimize-my-code-in-spring-mvc-controller-using-requestmapping by cc-by-sa and MIT license