Change configuration to make it easier to integrate with an existing Spring MVC application by implementing special MVC mapping and HanndlerAdapter beans that only recognize Spring Data REST components.

This commit is contained in:
Jon Brisbin
2012-06-22 12:15:25 -05:00
parent 0a05216b18
commit 25b8813604
4 changed files with 87 additions and 37 deletions

View File

@@ -0,0 +1,39 @@
package org.springframework.data.rest.webmvc;
import java.util.Arrays;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
/**
* @author Jon Brisbin
*/
public class RepositoryExporterHandlerAdapter extends RequestMappingHandlerAdapter {
public RepositoryExporterHandlerAdapter() {
setCustomArgumentResolvers(Arrays.asList(
new ServerHttpRequestMethodArgumentResolver(),
new PagingAndSortingMethodArgumentResolver()
));
// Add JSON converter for special Spring Data media type
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();
json.setSupportedMediaTypes(
Arrays.asList(MediaType.APPLICATION_JSON, MediaType.valueOf("application/x-spring-data+json"))
);
getMessageConverters().add(json);
}
@Override public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override protected boolean supportsInternal(HandlerMethod handlerMethod) {
return super.supportsInternal(handlerMethod)
&& RepositoryRestController.class.isAssignableFrom(handlerMethod.getBeanType());
}
}

View File

@@ -0,0 +1,32 @@
package org.springframework.data.rest.webmvc;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import org.springframework.core.Ordered;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
/**
* @author Jon Brisbin
*/
public class RepositoryExporterHandlerMapping extends RequestMappingHandlerMapping {
private EntityManagerFactory entityManagerFactory;
public RepositoryExporterHandlerMapping(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
setOrder(Ordered.HIGHEST_PRECEDENCE);
}
@Override protected boolean isHandler(Class<?> beanType) {
return RepositoryRestController.class.isAssignableFrom(beanType);
}
@Override protected void extendInterceptors(List<Object> interceptors) {
OpenEntityManagerInViewInterceptor omivi = new OpenEntityManagerInViewInterceptor();
omivi.setEntityManagerFactory(entityManagerFactory);
interceptors.add(omivi);
}
}

View File

@@ -65,7 +65,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
@@ -84,7 +83,6 @@ import org.springframework.web.util.UriComponentsBuilder;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Controller
public class RepositoryRestController
extends RepositoryExporterSupport<RepositoryRestController>
implements ApplicationContextAware,

View File

@@ -11,29 +11,21 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.Ordered;
import org.springframework.data.rest.repository.RepositoryExporter;
import org.springframework.data.rest.repository.context.ValidatingRepositoryEventListener;
import org.springframework.data.rest.repository.jpa.JpaRepositoryExporter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
import org.springframework.util.Assert;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Configuration
@EnableWebMvc
@ImportResource("classpath*:META-INF/spring-data-rest/**/*-export.xml")
public class RepositoryRestMvcConfiguration extends WebMvcConfigurerAdapter {
public class RepositoryRestMvcConfiguration {
ContentNegotiatingViewResolver viewResolver;
RepositoryRestController repositoryRestController;
@@ -50,39 +42,27 @@ public class RepositoryRestMvcConfiguration extends WebMvcConfigurerAdapter {
@Autowired(required = false)
ValidatingRepositoryEventListener validatingRepositoryEventListener;
@Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new ServerHttpRequestMethodArgumentResolver());
argumentResolvers.add(new PagingAndSortingMethodArgumentResolver());
}
RepositoryExporterHandlerAdapter repositoryExporterHandlerAdapter;
RepositoryExporterHandlerMapping repositoryExporterHandlerMapping;
@Override public void addInterceptors(InterceptorRegistry registry) {
registry.addWebRequestInterceptor(openEntityManagerInViewInterceptor());
}
@Bean List<HttpMessageConverter<?>> httpMessageConverters() {
Assert.notNull(httpMessageConverters);
if (httpMessageConverters.isEmpty()) {
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();
json.setSupportedMediaTypes(
Arrays.asList(MediaType.APPLICATION_JSON, MediaType.valueOf("application/x-spring-data+json"))
);
httpMessageConverters.add(json);
@Bean RepositoryExporterHandlerAdapter repositoryExporterHandlerAdapter() {
if (null == repositoryExporterHandlerAdapter) {
repositoryExporterHandlerAdapter = new RepositoryExporterHandlerAdapter();
}
return repositoryExporterHandlerAdapter;
}
return httpMessageConverters;
@Bean RepositoryExporterHandlerMapping repositoryExporterHandlerMapping() {
if (null == repositoryExporterHandlerMapping) {
repositoryExporterHandlerMapping = new RepositoryExporterHandlerMapping(entityManagerFactory);
}
return repositoryExporterHandlerMapping;
}
@Bean PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
return new PersistenceAnnotationBeanPostProcessor();
}
@Bean OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor() {
OpenEntityManagerInViewInterceptor oemiv = new OpenEntityManagerInViewInterceptor();
oemiv.setEntityManagerFactory(entityManagerFactory);
return oemiv;
}
@Bean JpaRepositoryExporter jpaRepositoryExporter() {
if (null == customJpaRepositoryExporter) {
return new JpaRepositoryExporter();
@@ -110,6 +90,7 @@ public class RepositoryRestMvcConfiguration extends WebMvcConfigurerAdapter {
@Bean ContentNegotiatingViewResolver contentNegotiatingViewResolver() {
if (null == viewResolver) {
viewResolver = new ContentNegotiatingViewResolver();
viewResolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
Map<String, String> mediaTypes = new HashMap<String, String>() {{
put("json", "application/json");
@@ -128,7 +109,7 @@ public class RepositoryRestMvcConfiguration extends WebMvcConfigurerAdapter {
if (null == repositoryRestController) {
this.repositoryRestController = new RepositoryRestController()
.repositoryExporters(Arrays.<RepositoryExporter>asList(jpaRepositoryExporter()))
.httpMessageConverters(httpMessageConverters())
.httpMessageConverters(repositoryExporterHandlerAdapter().getMessageConverters())
.jsonMediaType("application/json");
}
return repositoryRestController;