From b3290c190cd7fe79b8c26ef920d50b04ef362013 Mon Sep 17 00:00:00 2001 From: Jon Brisbin Date: Tue, 26 Jun 2012 11:24:52 -0500 Subject: [PATCH] Changed how handler mappings work in Spring Data REST so that only paths that have Repositories exported on them are recognized by the controller. This makes it easier to integrate the RepositoryRestController into an existing Spring MVC application because all you have to do is include the RepositoryRestMvcConfiguration JavaConfig bean into your existing application. Also included some changes to the way views are resolved so that only views starting with "org.springframework.data.rest" will be recognized as our own special views. --- .../RepositoryExporterHandlerMapping.java | 30 +++++++++++++++++++ .../rest/webmvc/RepositoryRestController.java | 10 +++++++ .../webmvc/RepositoryRestViewResolver.java | 5 +++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryExporterHandlerMapping.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryExporterHandlerMapping.java index 08a22d2a9..53147f474 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryExporterHandlerMapping.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryExporterHandlerMapping.java @@ -1,11 +1,17 @@ package org.springframework.data.rest.webmvc; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.persistence.EntityManagerFactory; +import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.Ordered; +import org.springframework.data.rest.repository.RepositoryExporter; import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; +import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; /** @@ -15,11 +21,35 @@ public class RepositoryExporterHandlerMapping extends RequestMappingHandlerMappi @Autowired private EntityManagerFactory entityManagerFactory; + @Autowired(required = false) + private List repositoryExporters = Collections.emptyList(); + private Set repositoryNames = new HashSet(); public RepositoryExporterHandlerMapping() { setOrder(Ordered.HIGHEST_PRECEDENCE); } + @SuppressWarnings({"unchecked"}) + @Override + protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception { + if (repositoryNames.isEmpty() && !repositoryExporters.isEmpty()) { + for (RepositoryExporter re : repositoryExporters) { + repositoryNames.addAll(re.repositoryNames()); + } + } + String[] parts = lookupPath.split("/"); + if (parts.length == 0) { + // Root request + return super.lookupHandlerMethod(lookupPath, request); + } else { + if (repositoryNames.contains(parts[1])) { + return super.lookupHandlerMethod(lookupPath, request); + } else { + return null; + } + } + } + @Override protected boolean isHandler(Class beanType) { return RepositoryRestController.class.isAssignableFrom(beanType); } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestController.java index cb7c21c68..1dd8e9e3c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestController.java @@ -48,6 +48,7 @@ import org.springframework.data.rest.repository.RepositoryConstraintViolationExc import org.springframework.data.rest.repository.RepositoryExporter; import org.springframework.data.rest.repository.RepositoryExporterSupport; import org.springframework.data.rest.repository.RepositoryMetadata; +import org.springframework.data.rest.repository.RepositoryNotFoundException; import org.springframework.data.rest.repository.RepositoryQueryMethod; import org.springframework.data.rest.repository.annotation.RestResource; import org.springframework.data.rest.repository.context.AfterDeleteEvent; @@ -1089,6 +1090,15 @@ public class RepositoryRestController return new ModelAndView(viewName("empty"), model); } + @ExceptionHandler(RepositoryNotFoundException.class) + @ResponseBody + public ResponseEntity handleRepositoryNotFoundFailure(RepositoryNotFoundException e) { + if (LOG.isWarnEnabled()) { + LOG.warn("RepositoryNotFoundException: " + e.getMessage()); + } + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + @SuppressWarnings({"unchecked"}) @ExceptionHandler(OptimisticLockingFailureException.class) @ResponseBody diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestViewResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestViewResolver.java index 168be80b7..c4fd0e95b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestViewResolver.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestViewResolver.java @@ -27,8 +27,11 @@ public class RepositoryRestViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { if (customViewMappings.containsKey(viewName)) { return customViewMappings.get(viewName); + } else if (viewName.startsWith("org.springframework.data.rest")) { + return view; + } else { + return null; } - return view; } }