Reorganize how configuration is loaded, add UUID/String Converters.

This commit is contained in:
Jon Brisbin
2012-05-07 10:26:27 -05:00
parent 61170d8b43
commit e44506c4e0
13 changed files with 341 additions and 238 deletions

View File

@@ -1,87 +0,0 @@
package org.springframework.data.rest.webmvc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
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.PersistenceAnnotationBeanPostProcessor;
/**
* Base configuration for the Spring Data REST Exporter.
*
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Configuration
public class RepositoryRestConfiguration {
@Autowired
EntityManagerFactory entityManagerFactory;
@Autowired(required = false)
JpaRepositoryExporter jpaRepositoryExporter;
@Autowired(required = false)
ConversionService customConversionService;
ConfigurableConversionService defaultConversionService = new DefaultConversionService();
@Autowired(required = false)
List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<HttpMessageConverter<?>>();
@Autowired(required = false)
ValidatingRepositoryEventListener validatingRepositoryEventListener;
/**
* Either the user's pre-configured {@link ConversionService} or the {@link DefaultConversionService}.
*
* @return
*/
@Bean ConversionService conversionService() {
if (null != customConversionService) {
return customConversionService;
} else {
return defaultConversionService;
}
}
/**
* A list of {@link HttpMessageConverter}s to be used to read incoming data and to write outgoing responses.
*
* @return
*/
@Bean List<HttpMessageConverter<?>> 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);
}
return httpMessageConverters;
}
/**
* Export any JPA {@link org.springframework.data.repository.Repository} implementations we find.
*
* @return
*/
@Bean JpaRepositoryExporter jpaRepositoryExporter() {
if (null == jpaRepositoryExporter) {
jpaRepositoryExporter = new JpaRepositoryExporter();
}
return jpaRepositoryExporter;
}
@Bean PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
return new PersistenceAnnotationBeanPostProcessor();
}
}

View File

@@ -19,11 +19,11 @@ import java.util.Stack;
import java.util.concurrent.atomic.AtomicReference;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.domain.Pageable;
@@ -33,6 +33,7 @@ import org.springframework.data.repository.Repository;
import org.springframework.data.rest.core.Handler;
import org.springframework.data.rest.core.Link;
import org.springframework.data.rest.core.SimpleLink;
import org.springframework.data.rest.core.convert.DelegatingConversionService;
import org.springframework.data.rest.core.util.UriUtils;
import org.springframework.data.rest.repository.AttributeMetadata;
import org.springframework.data.rest.repository.EntityMetadata;
@@ -48,11 +49,13 @@ import org.springframework.data.rest.repository.context.AfterSaveEvent;
import org.springframework.data.rest.repository.context.BeforeDeleteEvent;
import org.springframework.data.rest.repository.context.BeforeLinkSaveEvent;
import org.springframework.data.rest.repository.context.BeforeSaveEvent;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.server.ServerHttpRequest;
@@ -67,6 +70,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.util.UriComponentsBuilder;
@@ -76,7 +80,7 @@ import org.springframework.web.util.UriComponentsBuilder;
@Controller
public class RepositoryRestController
extends RepositoryExporterSupport<RepositoryRestController>
implements ApplicationEventPublisherAware,
implements ApplicationContextAware,
InitializingBean {
public static final String STATUS = "status";
@@ -86,17 +90,19 @@ public class RepositoryRestController
public static final String SELF = "self";
public static final String LINKS = "_links";
private ApplicationEventPublisher eventPublisher;
private ApplicationContext applicationContext;
private MediaType uriListMediaType = MediaType.parseMediaType("text/uri-list");
private MediaType jsonMediaType = MediaType.parseMediaType("application/x-spring-data+json");
private ConversionService conversionService = new DefaultConversionService();
private DelegatingConversionService conversionService = new DelegatingConversionService(
new DefaultFormattingConversionService()
);
private List<HttpMessageConverter<?>> httpMessageConverters = Collections.emptyList();
private Map<String, Handler<Object, Object>> resourceHandlers = Collections.emptyMap();
private ObjectMapper objectMapper = new ObjectMapper();
@Override public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ConversionService getConversionService() {
@@ -104,7 +110,9 @@ public class RepositoryRestController
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
if (null != conversionService) {
this.conversionService.addConversionServices(conversionService);
}
}
public ConversionService conversionService() {
@@ -112,7 +120,7 @@ public class RepositoryRestController
}
public RepositoryRestController conversionService(ConversionService conversionService) {
this.conversionService = conversionService;
setConversionService(conversionService);
return this;
}
@@ -121,6 +129,7 @@ public class RepositoryRestController
}
public void setHttpMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {
Assert.notNull(httpMessageConverters);
this.httpMessageConverters = httpMessageConverters;
}
@@ -129,7 +138,7 @@ public class RepositoryRestController
}
public RepositoryRestController httpMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {
this.httpMessageConverters = httpMessageConverters;
setHttpMessageConverters(httpMessageConverters);
return this;
}
@@ -147,7 +156,7 @@ public class RepositoryRestController
}
public RepositoryRestController resourceHandlers(Map<String, Handler<Object, Object>> resourceHandlers) {
this.resourceHandlers = resourceHandlers;
setResourceHandlers(resourceHandlers);
return this;
}
@@ -203,8 +212,8 @@ public class RepositoryRestController
return this;
}
@SuppressWarnings({"unchecked"})
@Override public void afterPropertiesSet() throws Exception {
Assert.notNull(httpMessageConverters, "HttpMessageConverters cannot be null");
}
@SuppressWarnings({"unchecked"})
@@ -400,12 +409,12 @@ public class RepositoryRestController
if (null == incoming) {
model.addAttribute(STATUS, HttpStatus.NOT_ACCEPTABLE);
} else {
if (null != eventPublisher) {
eventPublisher.publishEvent(new BeforeSaveEvent(incoming));
if (null != applicationContext) {
applicationContext.publishEvent(new BeforeSaveEvent(incoming));
}
Object savedEntity = repo.save(incoming);
if (null != eventPublisher) {
eventPublisher.publishEvent(new AfterSaveEvent(savedEntity));
if (null != applicationContext) {
applicationContext.publishEvent(new AfterSaveEvent(savedEntity));
}
String sId = repoMeta.entityMetadata().idAttribute().get(savedEntity).toString();
@@ -445,19 +454,20 @@ public class RepositoryRestController
model.addAttribute(STATUS, HttpStatus.NOT_FOUND);
} else {
HttpHeaders headers = new HttpHeaders();
Object version = repoMeta.entityMetadata().versionAttribute().get(entity);
if (null != version) {
List<String> etags = request.getHeaders().getIfNoneMatch();
for (String etag : etags) {
if (("\"" + version.toString() + "\"").equals(etag)) {
model.addAttribute(STATUS, HttpStatus.NOT_MODIFIED);
return;
if (null != repoMeta.entityMetadata().versionAttribute()) {
Object version = repoMeta.entityMetadata().versionAttribute().get(entity);
if (null != version) {
List<String> etags = request.getHeaders().getIfNoneMatch();
for (String etag : etags) {
if (("\"" + version.toString() + "\"").equals(etag)) {
model.addAttribute(STATUS, HttpStatus.NOT_MODIFIED);
return;
}
}
headers.set("ETag", "\"" + version.toString() + "\"");
}
headers.set("ETag", "\"" + version.toString() + "\"");
}
Map<String, Object> entityDto = extractPropertiesLinkAware(repository,
repoMeta.rel(),
Map<String, Object> entityDto = extractPropertiesLinkAware(repoMeta.rel(),
entity,
repoMeta.entityMetadata(),
buildUri(baseUri, repository, id));
@@ -520,12 +530,12 @@ public class RepositoryRestController
} else {
repoMeta.entityMetadata().idAttribute().set(serId, incoming);
if (request.getMethod() == HttpMethod.POST) {
if (null != eventPublisher) {
eventPublisher.publishEvent(new BeforeSaveEvent(incoming));
if (null != applicationContext) {
applicationContext.publishEvent(new BeforeSaveEvent(incoming));
}
Object savedEntity = repo.save(incoming);
if (null != eventPublisher) {
eventPublisher.publishEvent(new AfterSaveEvent(savedEntity));
if (null != applicationContext) {
applicationContext.publishEvent(new AfterSaveEvent(savedEntity));
}
URI selfUri = buildUri(baseUri, repository, id);
HttpHeaders headers = new HttpHeaders();
@@ -533,12 +543,12 @@ public class RepositoryRestController
model.addAttribute(HEADERS, headers);
model.addAttribute(STATUS, HttpStatus.CREATED);
} else {
if (null != eventPublisher) {
eventPublisher.publishEvent(new BeforeSaveEvent(incoming));
if (null != applicationContext) {
applicationContext.publishEvent(new BeforeSaveEvent(incoming));
}
Object savedEntity = repo.save(incoming);
if (null != eventPublisher) {
eventPublisher.publishEvent(new AfterSaveEvent(savedEntity));
if (null != applicationContext) {
applicationContext.publishEvent(new AfterSaveEvent(savedEntity));
}
model.addAttribute(STATUS, HttpStatus.NO_CONTENT);
}
@@ -561,12 +571,12 @@ public class RepositoryRestController
.type());
CrudRepository repo = repoMeta.repository();
if (null != eventPublisher) {
eventPublisher.publishEvent(new BeforeDeleteEvent(serId));
if (null != applicationContext) {
applicationContext.publishEvent(new BeforeDeleteEvent(serId));
}
repo.delete(serId);
if (null != eventPublisher) {
eventPublisher.publishEvent(new AfterDeleteEvent(serId));
if (null != applicationContext) {
applicationContext.publishEvent(new AfterDeleteEvent(serId));
}
model.addAttribute(STATUS, HttpStatus.NO_CONTENT);
@@ -752,15 +762,15 @@ public class RepositoryRestController
}
}
if (null != eventPublisher) {
eventPublisher.publishEvent(new BeforeSaveEvent(entity));
eventPublisher.publishEvent(new BeforeLinkSaveEvent(entity, linked));
if (null != applicationContext) {
applicationContext.publishEvent(new BeforeSaveEvent(entity));
applicationContext.publishEvent(new BeforeLinkSaveEvent(entity, linked));
}
Object savedEntity = repo.save(entity);
if (null != eventPublisher) {
if (null != applicationContext) {
linked = attrMeta.get(savedEntity);
eventPublisher.publishEvent(new AfterLinkSaveEvent(savedEntity, linked));
eventPublisher.publishEvent(new AfterSaveEvent(savedEntity));
applicationContext.publishEvent(new AfterLinkSaveEvent(savedEntity, linked));
applicationContext.publishEvent(new AfterSaveEvent(savedEntity));
}
if (request.getMethod() == HttpMethod.PUT) {
@@ -798,12 +808,12 @@ public class RepositoryRestController
Object linked = attrMeta.get(entity);
attrMeta.set(null, entity);
if (null != eventPublisher) {
eventPublisher.publishEvent(new BeforeLinkSaveEvent(entity, linked));
if (null != applicationContext) {
applicationContext.publishEvent(new BeforeLinkSaveEvent(entity, linked));
}
Object savedEntity = repo.save(entity);
if (null != eventPublisher) {
eventPublisher.publishEvent(new AfterLinkSaveEvent(savedEntity, null));
if (null != applicationContext) {
applicationContext.publishEvent(new AfterLinkSaveEvent(savedEntity, null));
}
model.addAttribute(STATUS, HttpStatus.NO_CONTENT);
@@ -844,15 +854,14 @@ public class RepositoryRestController
// Find linked entity
RepositoryMetadata linkedRepoMeta = repositoryMetadataFor(attrMeta);
if (null != linkedRepoMeta) {
CrudRepository linkedRepo = (CrudRepository) linkedRepoMeta.repository();
CrudRepository linkedRepo = linkedRepoMeta.repository();
Serializable sChildId = stringToSerializable(linkedId,
(Class<? extends Serializable>) linkedRepoMeta.entityMetadata()
.idAttribute()
.type());
Object linkedEntity = linkedRepo.findOne(sChildId);
if (null != linkedEntity) {
Map<String, Object> entityDto = extractPropertiesLinkAware(repository,
linkedRepoMeta.rel(),
Map<String, Object> entityDto = extractPropertiesLinkAware(linkedRepoMeta.rel(),
linkedEntity,
linkedRepoMeta.entityMetadata(),
baseUri);
@@ -908,18 +917,18 @@ public class RepositoryRestController
if (null != linkedEntity) {
// Remove linked entity from relationship based on property type
if (attrMeta.isCollectionLike()) {
Collection c = (Collection) attrMeta.get(entity);
Collection c = attrMeta.asCollection(entity);
if (null != c) {
c.remove(linkedEntity);
}
} else if (attrMeta.isSetLike()) {
Set s = (Set) attrMeta.get(entity);
Set s = attrMeta.asSet(entity);
if (null != s) {
s.remove(linkedEntity);
}
} else if (attrMeta.isMapLike()) {
Object keyToRemove = null;
Map<Object, Object> m = (Map) attrMeta.get(entity);
Map<Object, Object> m = attrMeta.asMap(entity);
if (null != m) {
for (Map.Entry<Object, Object> entry : m.entrySet()) {
Object val = entry.getValue();
@@ -948,15 +957,13 @@ public class RepositoryRestController
@SuppressWarnings({"unchecked"})
@ExceptionHandler(OptimisticLockingFailureException.class)
public Model handleLockingFailure(OptimisticLockingFailureException ex) throws IOException {
Model model = new ExtendedModelMap();
model.addAttribute(STATUS, HttpStatus.CONFLICT);
@ResponseBody
public ResponseEntity handleLockingFailure(OptimisticLockingFailureException ex) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
Map m = new HashMap();
m.put("message", ex.getMessage());
model.addAttribute(RESOURCE, m);
return model;
return new ResponseEntity(objectMapper.writeValueAsBytes(m), headers, HttpStatus.CONFLICT);
}
@SuppressWarnings({"unchecked"})
@@ -1042,8 +1049,7 @@ public class RepositoryRestController
}
@SuppressWarnings({"unchecked"})
private Map<String, Object> extractPropertiesLinkAware(String repoName,
String repoRel,
private Map<String, Object> extractPropertiesLinkAware(String repoRel,
Object entity,
EntityMetadata<AttributeMetadata> entityMetadata,
URI baseUri) {
@@ -1057,14 +1063,18 @@ public class RepositoryRestController
}
}
List<Link> links = (List<Link>) entityDto.get(LINKS);
if (null == links) {
links = new ArrayList<Link>();
entityDto.put(LINKS, links);
}
for (String attrName : entityMetadata.linkedAttributes().keySet()) {
links.add(new SimpleLink(repoRel + "." + entity.getClass().getSimpleName() + "." + attrName,
buildUri(baseUri, attrName)));
URI uri = UriComponentsBuilder.fromUri(baseUri)
.pathSegment(attrName)
.build()
.toUri();
Link l = new SimpleLink(repoRel + "." + entity.getClass().getSimpleName() + "." + attrName, uri);
List<Link> links = (List<Link>) entityDto.get(LINKS);
if (null == links) {
links = new ArrayList<Link>();
entityDto.put(LINKS, links);
}
links.add(l);
}
return entityDto;

View File

@@ -0,0 +1,26 @@
package org.springframework.data.rest.webmvc;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class RepositoryRestExporterServlet extends DispatcherServlet {
public RepositoryRestExporterServlet() {
configure();
}
public RepositoryRestExporterServlet(WebApplicationContext webApplicationContext) {
super(webApplicationContext);
configure();
}
private void configure() {
setContextClass(AnnotationConfigWebApplicationContext.class);
setContextConfigLocation(RepositoryRestMvcConfiguration.class.getName());
}
}

View File

@@ -1,14 +1,26 @@
package org.springframework.data.rest.webmvc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
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.convert.ConversionService;
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.View;
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
@@ -22,13 +34,66 @@ import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Configuration
@ImportResource("classpath*:META-INF/spring-data-rest/**/*-export.xml")
public class RepositoryRestMvcConfiguration {
@Autowired
RepositoryRestConfiguration parentConfig;
RepositoryRestController repositoryRestController;
@Autowired(required = false)
ContentNegotiatingViewResolver viewResolver;
RepositoryRestController repositoryRestController;
@Autowired
EntityManagerFactory entityManagerFactory;
@Autowired(required = false)
JpaRepositoryExporter customJpaRepositoryExporter;
@Autowired(required = false)
ConversionService customConversionService;
@Autowired(required = false)
List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<HttpMessageConverter<?>>();
@Autowired(required = false)
ValidatingRepositoryEventListener validatingRepositoryEventListener;
@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);
}
return httpMessageConverters;
}
@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();
} else {
return customJpaRepositoryExporter;
}
}
@Bean ValidatingRepositoryEventListener validatingRepositoryEventListener() {
if (null == validatingRepositoryEventListener) {
return new ValidatingRepositoryEventListener();
} else {
return validatingRepositoryEventListener;
}
}
@Bean ContentNegotiatingViewResolver contentNegotiatingViewResolver() {
if (null == viewResolver) {
@@ -50,21 +115,16 @@ public class RepositoryRestMvcConfiguration {
@Bean RepositoryRestController repositoryRestController() throws Exception {
if (null == repositoryRestController) {
this.repositoryRestController = new RepositoryRestController()
.conversionService(parentConfig.conversionService())
.httpMessageConverters(parentConfig.httpMessageConverters())
.repositoryExporters(Arrays.<RepositoryExporter>asList(jpaRepositoryExporter()))
.httpMessageConverters(httpMessageConverters())
.jsonMediaType("application/json");
if (null != customConversionService) {
repositoryRestController.conversionService(customConversionService);
}
}
return repositoryRestController;
}
@Bean ValidatingRepositoryEventListener validatingRepositoryEventListener() {
if (null == parentConfig.validatingRepositoryEventListener) {
return new ValidatingRepositoryEventListener();
}
return parentConfig.validatingRepositoryEventListener;
}
@Bean RequestMappingHandlerMapping handlerMapping() {
return new RequestMappingHandlerMapping();
}

View File

@@ -4,44 +4,12 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:META-INF/spring-data-rest/**/*-export.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>exporter</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
org.springframework.data.rest.webmvc.RepositoryRestConfiguration
org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration
</param-value>
</init-param>
<servlet-class>org.springframework.data.rest.webmvc.RepositoryRestExporterServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<filter>
<filter-name>entityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>entityManagerInViewFilter</filter-name>
<servlet-name>exporter</servlet-name>
</filter-mapping>
<servlet-mapping>
<servlet-name>exporter</servlet-name>
<url-pattern>/*</url-pattern>

View File

@@ -7,7 +7,6 @@ import org.springframework.context.support.ClassPathXmlApplicationContext
import org.springframework.data.rest.core.SimpleLink
import org.springframework.data.rest.core.util.FluentBeanSerializer
import org.springframework.data.rest.test.webmvc.Address
import org.springframework.data.rest.webmvc.RepositoryRestConfiguration
import org.springframework.data.rest.webmvc.RepositoryRestController
import org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration
import org.springframework.http.HttpStatus
@@ -49,18 +48,20 @@ class RepositoryRestControllerSpec extends Specification {
* Try to set up things similarly to how they get loaded in the webapp.
*/
def setupSpec() {
def appCtx = new ClassPathXmlApplicationContext("classpath*:META-INF/spring-data-rest/**/*-export.xml")
emf = appCtx.getBean(EntityManagerFactory)
def servletConfig = new MockServletConfig()
def servletContext = new MockServletContext()
def parentCtx = new ClassPathXmlApplicationContext("classpath*:META-INF/spring-data-rest/**/*-export.xml")
def webAppCtx = new AnnotationConfigWebApplicationContext()
webAppCtx.setServletConfig(new MockServletConfig())
webAppCtx.setServletContext(new MockServletContext())
webAppCtx.setConfigLocations([RepositoryRestConfiguration.name, RepositoryRestMvcConfiguration.name] as String[])
webAppCtx.setParent(appCtx)
webAppCtx.afterPropertiesSet()
webAppCtx.servletConfig = servletConfig
webAppCtx.servletContext = servletContext
webAppCtx.configLocations = [RepositoryRestMvcConfiguration.name] as String[]
webAppCtx.parent = parentCtx
webAppCtx.refresh()
emf = webAppCtx.getBean(EntityManagerFactory)
controller = webAppCtx.getBean(RepositoryRestController)
uriBuilder = UriComponentsBuilder.fromUriString("http://localhost:8080/data")
def customSerializerFactory = new CustomSerializerFactory()

View File

@@ -9,6 +9,25 @@
<jpa:repositories base-package="org.springframework.data.rest.test.webmvc"/>
<!--
If you need to add Converters to the REST exporter to handle the property types you're using
in your entities, then just configure a ConversionServiceFactoryBean here, add the Converteres
you need, and they will, in turn, be added to the FormattingConversionService the REST exporter
uses internally.
Uncomment this block to add the included UUID <-> String converters, which are not included by default.
-->
<!--
<bean class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.springframework.data.rest.core.convert.StringToUUIDConverter"/>
<bean class="org.springframework.data.rest.core.convert.UUIDToStringConverter"/>
</set>
</property>
</bean>
-->
<!--
This validator will be picked up automatically. The default configuration is to look at the bean name
and figure out what event you're interested in. This validator is interested in 'beforeSave' events

View File

@@ -5,10 +5,6 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<bean id="baseUri" class="java.net.URI">
<constructor-arg value="http://localhost:8080/data"/>
</bean>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">