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.
This commit is contained in:
Jon Brisbin
2012-06-26 11:24:52 -05:00
parent ebd50e96e7
commit b3290c190c
3 changed files with 44 additions and 1 deletions

View File

@@ -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<RepositoryExporter> repositoryExporters = Collections.emptyList();
private Set<String> repositoryNames = new HashSet<String>();
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);
}

View File

@@ -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

View File

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