Including HAL-browser in Spring Boot without using Spring Data REST

First of all, if you are using Spring Data REST to expose your repository through an API, including and using the HAL-browser is a very simple step. The only thing you have to do is to add the following dependency to your Gradle build file.
1 |
compile ('org.springframework.data:spring-data-rest-hal-browser') |
After that you can reach the HAL-browser at http://<host>:<port>/browser/index.html and traverse the API. Moreover, if you are using CURIEs the HAL-browser also includes easily accessible links to your documentation and integrates it within the browser.
But the spring-data-rest-hal-browser is not only a simple wrapper of the original HAL-browser. It requires some more dependencies including Spring Data REST Webmvc and as soon as this library is on your classpath it performs some “magic” or autoconfiguration. For example it exposes some application/alps json metadata (profile) endpoint and far worse than that it exposes all endpoints defined in your Spring repositories, even the DELETE method is suddenly available for your endpoint. Of course this behavior can be disabled by adding the main Spring Data Rest project as a dependency and configuring the repository to be not exported (like shown in the code below – reference). But overall it seems not reasonable to invest that amount of effort just because of the handy HAL-browser. And in some cases you don’t even need or want a new dependency like Spring Data Rest and to take all these additional steps.
1 2 3 |
@RepositoryRestResource(exported = false) public interface BooksRepository extends MongoRepository<Book, Long> { } |
We want to introduce two alternatives how to include onlyx the HAL-browser without any additional dependency and a minimum of configuration:
- One way is to add a special resource handler
- The other one is to include it by adding a Gradle task
For that we use the HAL-browser package provided by Webjars. A Webjar is a client-side web framework or library that is packaged into a JAR file. Therefore the packaged library can easily be integrated into a Java application with the help of your favorite dependency management tool.
So everything we have to do is to add the correct Webjar to our Gradle dependencies block in our case. After that you can choose between the two described alternatives.
1 |
compile 'org.webjars:hal-browser:b7669f1-1' |
Option 1: Webjar Resource handler
First we want to show you how to serve the browser with Spring by adding a special resource handler to your configuration (for more details see here):
1 2 3 4 5 6 7 |
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!registry.hasMappingForPattern("/browser/**")) { registry.addResourceHandler("/browser/**").addResourceLocations( "classpath:/META-INF/resources/webjars/hal-browser/"); } } |
This will serve the HAL-browser at http://<host>:<port>/browser/browser.html.
Option 2: Webjar Gradle task
The second option is to add a Gradle task that basically extracts the needed files from the webjar, strips the version information from folder structure and copies them into the “static/” folder of your JAR. This is then served by Spring automatically, without any additional configuration.
For that we added a configuration “halbrowser” and the “halbrowser” task to our build file and configured the “jar” and “bootRun” steps to depend on this task.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
buildscript { ext { springBootVersion = '1.5.6.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 configurations { halbrowser } repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') halbrowser 'org.webjars:hal-browser:b7669f1-1' } task halbrowser (type: Copy) { Dependency dependency = project.configurations.halbrowser.dependencies[0] from(project.zipTree(project.configurations.halbrowser.files.find { it.path.contains(dependency.group + File.separator + dependency.name + File.separator + dependency.version) })) { exclude { it.file.isDirectory() } eachFile { details -> def targetPath = (details.path - "META-INF/resources/webjars/hal-browser/${dependency.version}/".toString()) details.path = targetPath } include "**/resources/webjars/hal-browser/*/**" } into "${sourceSets.main.output.resourcesDir}/static/browser/" } jar { dependsOn halbrowser } bootRun { dependsOn halbrowser } |
After you run the resulting JAR from the Gradle build or start it with bootRun, the HAL-browser will also be served at http://<host>:<port>/browser/browser.html. If not, check if your Spring app serves static content which is the default configuration in a Spring Boot application, but you can also configure it by yourself, see Configuring Serving of Resources.
We prefer the Gradle task because it doesn’t even force us to change one line of our application code. But both solutions are valid and have the same effect in the end.
If you have any questions or want to give some suggestions just leave a comment.
Comment article
Recent posts






Comments
Adrian
Hi I tried the first approach but it didn’t work. I am using Spring Boot 2 and have configured the resource handler via WebMvcConfigurer
Adrian
Hi I tried the first approach but it didn’t work. I am using Spring Boot 2 and have configured the resource handler via WebMvcConfigurer