diff --git a/src/main/java/com/eactive/httpmockserver/api/controller/MockApiController.java b/src/main/java/com/eactive/httpmockserver/api/controller/MockApiController.java index ed39b9d..47f0b4e 100644 --- a/src/main/java/com/eactive/httpmockserver/api/controller/MockApiController.java +++ b/src/main/java/com/eactive/httpmockserver/api/controller/MockApiController.java @@ -12,7 +12,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.AntPathMatcher; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @@ -28,6 +27,7 @@ public class MockApiController { private final MockRouteService mockRouteService; Map matchers; + public MockApiController(MockRouteService mockRouteService) { this.mockRouteService = mockRouteService; this.matchers = new ConcurrentHashMap<>(); @@ -38,12 +38,9 @@ public class MockApiController { } - - //logger private static final Logger logger = LoggerFactory.getLogger(MockApiController.class); - @RequestMapping(value = "/{_:^(?!swagger-ui|mgmt|min-maps|plugins|dist|css|fonts|js|h2-console|img|pages|favicon.ico).*$}/**") public ResponseEntity handleRequest(HttpServletRequest httpRequest) throws IOException { MockRequest request = new MockRequest(httpRequest); AntPathMatcher pathMatcher = new AntPathMatcher(); diff --git a/src/main/java/com/eactive/httpmockserver/api/controller/MockApiHandlerMapping.java b/src/main/java/com/eactive/httpmockserver/api/controller/MockApiHandlerMapping.java new file mode 100644 index 0000000..aaf0d35 --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/api/controller/MockApiHandlerMapping.java @@ -0,0 +1,61 @@ +package com.eactive.httpmockserver.api.controller; + +import com.eactive.httpmockserver.api.entity.MockRoute; +import com.eactive.httpmockserver.api.service.MockRouteService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; + +@Component +public class MockApiHandlerMapping { + + private static final Logger logger = LoggerFactory.getLogger(MockApiHandlerMapping.class); + + @Autowired + private MockRouteService mockRouteService; + + @Autowired + private MockApiController mockApiController; + + @Autowired + private RequestMappingHandlerMapping requestMappingHandlerMapping; + + @PostConstruct + public void initialize() { + mockRouteService.initAllRoutes(); + for (MockRoute mockRoute : mockRouteService.getAllRoutes()) { + registerMapping(mockRoute); + } + } + + public void registerMapping(MockRoute mockRoute) { + RequestMappingInfo mappingInfo = RequestMappingInfo + .paths(mockRoute.getPathPattern()) + .methods(RequestMethod.valueOf(mockRoute.getMethod())) + .build(); + + try { + requestMappingHandlerMapping.registerMapping(mappingInfo, mockApiController, MockApiController.class.getDeclaredMethod("handleRequest", HttpServletRequest.class)); + logger.info("Registered mapping for {} {}", mockRoute.getMethod(), mockRoute.getPathPattern()); + } catch (NoSuchMethodException e) { + logger.error("Error registering mapping", e); + } + } + + public void unregisterMapping(MockRoute mockRoute) { + RequestMappingInfo mappingInfo = RequestMappingInfo + .paths(mockRoute.getPathPattern()) + .methods(RequestMethod.valueOf(mockRoute.getMethod())) + .build(); + + requestMappingHandlerMapping.unregisterMapping(mappingInfo); + logger.info("Unregistered mapping for {} {}", mockRoute.getMethod(), mockRoute.getPathPattern()); + } +} diff --git a/src/main/java/com/eactive/httpmockserver/api/controller/MockRouteMgmtController.java b/src/main/java/com/eactive/httpmockserver/api/controller/MockRouteMgmtController.java index 5850b73..d68fe5b 100644 --- a/src/main/java/com/eactive/httpmockserver/api/controller/MockRouteMgmtController.java +++ b/src/main/java/com/eactive/httpmockserver/api/controller/MockRouteMgmtController.java @@ -39,6 +39,10 @@ public class MockRouteMgmtController { @Autowired private MockRouteMapper mockRouteMapper; + @Autowired + private MockApiHandlerMapping mockApiHandlerMapping; + + public static final String MOCK_ROUTE_EDIT = "page/routes/mockRouteEdit"; public static final String MOCK_ROUTE_LIST_VIEW = "redirect:/mgmt/routes/list_view.do"; @@ -89,6 +93,7 @@ public class MockRouteMgmtController { MockRoute mockRoute = mockRouteMapper.map(dto); mockRouteService.create(mockRoute); mockRouteService.initAllRoutes(); + mockApiHandlerMapping.registerMapping(mockRoute); return MOCK_ROUTE_LIST_VIEW; } @@ -109,9 +114,14 @@ public class MockRouteMgmtController { return MOCK_ROUTE_EDIT; } + MockRoute prev = mockRouteService.findById(Long.parseLong(id)); + mockApiHandlerMapping.unregisterMapping(prev); + MockRoute mockRoute = mockRouteMapper.map(dto); mockRouteService.update(Long.parseLong(id), mockRoute); mockRouteService.initAllRoutes(); + + mockApiHandlerMapping.registerMapping(mockRoute); return MOCK_ROUTE_LIST_VIEW; } @@ -119,6 +129,8 @@ public class MockRouteMgmtController { @PostMapping("/delete.do") public String delete(@RequestParam("checkedIdForDel") List ids) { for (String id : ids) { + MockRoute mockRoute = mockRouteService.findById(Long.parseLong(id)); + mockApiHandlerMapping.unregisterMapping(mockRoute); mockRouteService.deleteById(Long.parseLong(id)); } mockRouteService.initAllRoutes(); diff --git a/src/main/java/com/eactive/httpmockserver/api/service/MockRouteService.java b/src/main/java/com/eactive/httpmockserver/api/service/MockRouteService.java index c6d5860..9c3f467 100644 --- a/src/main/java/com/eactive/httpmockserver/api/service/MockRouteService.java +++ b/src/main/java/com/eactive/httpmockserver/api/service/MockRouteService.java @@ -113,8 +113,7 @@ public class MockRouteService { try { MockRoute cloned = (MockRoute) BeanUtils.cloneBean(route); allRoutes.add(cloned); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException | - NoSuchMethodException e) { + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException(e); } } diff --git a/src/main/java/com/eactive/httpmockserver/config/WebMvcConfig.java b/src/main/java/com/eactive/httpmockserver/config/WebMvcConfig.java index 52ff01b..44d1895 100644 --- a/src/main/java/com/eactive/httpmockserver/config/WebMvcConfig.java +++ b/src/main/java/com/eactive/httpmockserver/config/WebMvcConfig.java @@ -19,78 +19,80 @@ import java.util.concurrent.TimeUnit; @EnableWebMvc public class WebMvcConfig implements WebMvcConfigurer { - @Override - public void addViewControllers(ViewControllerRegistry registry) { - registry.setOrder(Ordered.HIGHEST_PRECEDENCE); - WebMvcConfigurer.super.addViewControllers(registry); - } - private List listAdminAuthPattern() { - List patterns = new ArrayList<>(); - patterns.add("/mgmt/users/*.do"); - patterns.add("/mgmt/servers/*.do"); - return patterns; - } + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.setOrder(Ordered.HIGHEST_PRECEDENCE); + WebMvcConfigurer.super.addViewControllers(registry); + } - @Bean - public AuthenticInterceptor authenticInterceptor() { - AuthenticInterceptor authenticInterceptor = new AuthenticInterceptor(); - authenticInterceptor.setAdminAuthPatternList(listAdminAuthPattern()); - return authenticInterceptor; - } + private List listAdminAuthPattern() { + List patterns = new ArrayList<>(); + patterns.add("/mgmt/users/*.do"); + patterns.add("/mgmt/servers/*.do"); + return patterns; + } - @Override - public void addArgumentResolvers(List resolvers) { - resolvers.add(pageableHandlerMethodArgumentResolver()); - } + @Bean + public AuthenticInterceptor authenticInterceptor() { + AuthenticInterceptor authenticInterceptor = new AuthenticInterceptor(); + authenticInterceptor.setAdminAuthPatternList(listAdminAuthPattern()); + return authenticInterceptor; + } - @Bean - public PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver() { - PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver = new PageableHandlerMethodArgumentResolver(); - pageableHandlerMethodArgumentResolver.setOneIndexedParameters(true); //1부터 시작 - pageableHandlerMethodArgumentResolver.setFallbackPageable(PageRequest.of(0, 10)); //파라미터 없을 때 기본 페이지 - return pageableHandlerMethodArgumentResolver; - } - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(authenticInterceptor()) - .addPathPatterns( - "/", - "/mgmt/**/*.do") - .excludePathPatterns( - "/h2-console/**", - "/css/**", - "/html/**", - "/images/**", - "/img/**", - "/js/**", - "/login", - "/intro.do", - "/join.do", - "/user_register.do", - "/actionLogin.do", - "/check_id.do", - "/search_id.do", - "/admin_register_view.do", - "/admin_register.do", - "/request_register_auth.do", - "/reset_password.do", - "/forgot_password.do" - ); - } + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(pageableHandlerMethodArgumentResolver()); + } - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { + @Bean + public PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver() { + PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver = new PageableHandlerMethodArgumentResolver(); + pageableHandlerMethodArgumentResolver.setOneIndexedParameters(true); //1부터 시작 + pageableHandlerMethodArgumentResolver.setFallbackPageable(PageRequest.of(0, 10)); //파라미터 없을 때 기본 페이지 + return pageableHandlerMethodArgumentResolver; + } - registry.addResourceHandler("/css/**").addResourceLocations("/css/", "classpath:/static/css/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/", "classpath:/static/fonts/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/font/**").addResourceLocations("/font/", "classpath:/static/fonts/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/html/**").addResourceLocations("/html/", "classpath:/static/html/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/images/**").addResourceLocations("/images/", "classpath:/static/images/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/img/**").addResourceLocations("/img/", "classpath:/static/img/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/js/**").addResourceLocations("/js/", "classpath:/static/js/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/", "classpath:/static/plugins/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/min-maps/**").addResourceLocations("/min-maps/", "classpath:/static/plugins/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - registry.addResourceHandler("/favicon.ico").addResourceLocations("/favicon.ico", "classpath:/static/favicon.ico").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); - } + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(authenticInterceptor()) + .addPathPatterns( + "/", + "/mgmt/**/*.do") + .excludePathPatterns( + "/h2-console/**", + "/css/**", + "/html/**", + "/images/**", + "/img/**", + "/js/**", + "/login", + "/intro.do", + "/join.do", + "/user_register.do", + "/actionLogin.do", + "/check_id.do", + "/search_id.do", + "/admin_register_view.do", + "/admin_register.do", + "/request_register_auth.do", + "/reset_password.do", + "/forgot_password.do" + ); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + + registry.addResourceHandler("/css/**").addResourceLocations("/css/", "classpath:/static/css/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/", "classpath:/static/fonts/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/font/**").addResourceLocations("/font/", "classpath:/static/fonts/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/html/**").addResourceLocations("/html/", "classpath:/static/html/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/images/**").addResourceLocations("/images/", "classpath:/static/images/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/img/**").addResourceLocations("/img/", "classpath:/static/img/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/js/**").addResourceLocations("/js/", "classpath:/static/js/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/", "classpath:/static/plugins/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/min-maps/**").addResourceLocations("/min-maps/", "classpath:/static/plugins/").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + registry.addResourceHandler("/favicon.ico").addResourceLocations("/favicon.ico", "classpath:/static/favicon.ico").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)).resourceChain(true).addResolver(new PathResourceResolver()); + } }