DATAREST-293 - Added new module to easily add a HAL browser to Spring Data REST apps.
Added a module that repackages the webjar version of the HAL browser. The repackaging is necessary to be able to control the exposure of the browser dynamically and prevent Spring Boot's auto-exposure of webjars from kicking in. Tweaked BasePathAwareHandlerMapping to default the Accept header to the one defined in the configuration if none is present in the request or */* is given. This will make sure we default to a JSON dialect in case no header is set.
This commit is contained in:
@@ -21,8 +21,10 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -37,12 +39,17 @@ import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
@@ -72,6 +79,36 @@ public class BasePathAwareHandlerMapping extends RequestMappingHandlerMapping {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod(java.lang.String, javax.servlet.http.HttpServletRequest)
|
||||
*/
|
||||
@Override
|
||||
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
|
||||
|
||||
List<MediaType> mediaTypes = new ArrayList<MediaType>();
|
||||
boolean defaultFound = false;
|
||||
|
||||
for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader(HttpHeaders.ACCEPT))) {
|
||||
|
||||
MediaType rawtype = mediaType.removeQualityValue();
|
||||
|
||||
if (rawtype.equals(configuration.getDefaultMediaType())) {
|
||||
defaultFound = true;
|
||||
}
|
||||
|
||||
if (!rawtype.equals(MediaType.ALL)) {
|
||||
mediaTypes.add(mediaType);
|
||||
}
|
||||
}
|
||||
|
||||
if (!defaultFound) {
|
||||
mediaTypes.add(configuration.getDefaultMediaType());
|
||||
}
|
||||
|
||||
return super.lookupHandlerMethod(lookupPath, new CustomAcceptHeaderHttpServletRequest(request, mediaTypes));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#getMappingForMethod(java.lang.reflect.Method, java.lang.Class)
|
||||
@@ -495,4 +532,44 @@ public class BasePathAwareHandlerMapping extends RequestMappingHandlerMapping {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link HttpServletRequest} that exposes the given media types for the {@code Accept} header.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class CustomAcceptHeaderHttpServletRequest extends HttpServletRequestWrapper {
|
||||
|
||||
private final List<MediaType> acceptMediaTypes;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CustomAcceptHeaderHttpServletRequest} for the given delegate {@link HttpServletRequest} and
|
||||
* the list of {@link MediaType}.
|
||||
*
|
||||
* @param request must not be {@literal null}.
|
||||
* @param acceptMediaTypes must not be {@literal null} or empty.
|
||||
*/
|
||||
public CustomAcceptHeaderHttpServletRequest(HttpServletRequest request, List<MediaType> acceptMediaTypes) {
|
||||
|
||||
super(request);
|
||||
|
||||
Assert.notEmpty(acceptMediaTypes, "MediaTypes must not be empty!");
|
||||
|
||||
this.acceptMediaTypes = acceptMediaTypes;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.servlet.http.HttpServletRequestWrapper#getHeader(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
|
||||
if (HttpHeaders.ACCEPT.equalsIgnoreCase(name) && acceptMediaTypes != null) {
|
||||
return StringUtils.collectionToCommaDelimitedString(acceptMediaTypes);
|
||||
}
|
||||
|
||||
return super.getHeader(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
@@ -723,6 +724,28 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
|
||||
return new AlpsResourceProcessor(config());
|
||||
}
|
||||
|
||||
//
|
||||
// HAL Browser
|
||||
//
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addResourceHandlers(org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry)
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
|
||||
// Register HAL browser if present
|
||||
|
||||
if (ClassUtils.isPresent("org.springframework.data.rest.webmvc.halbrowser.HalBrowser", getClass().getClassLoader())) {
|
||||
|
||||
String basePath = config().getBasePath().toString().concat("/browser");
|
||||
String rootLocation = "classpath:META-INF/spring-data-rest/hal-browser/";
|
||||
|
||||
registry.addResourceHandler(basePath.concat("/**")).addResourceLocations(rootLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResourceSupportHttpMessageConverter extends TypeConstrainedMappingJackson2HttpMessageConverter
|
||||
implements Ordered {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user