Skip to main content

Spring Boot and Jersey (JAX-RS) static files support

In Spring Boot support for Jersey is provided by org.springframework.boot:spring-boot-starter-jersey Gradle dependency. When the static file URL pattern is matched with URLs that Jersey handles, additional configurations are required for Spring Boot to serve static resources.

Note: We are using Gradle dependency management system, configuration for Maven will be similar.

Add Spring Boot web starter dependency

File : build.gradle (Snippet)

dependencies {
     compile 'org.springframework.boot:spring-boot-starter-web',
     		 'org.springframework.boot:spring-boot-starter-jersey', 
    		 'org.springframework.boot:spring-boot-devtools'
    		 
    testCompile 'org.springframework.boot:spring-boot-starter-test'
}

Add org.springframework.boot:spring-boot-starter-web to enable Spring Web application support. We need @SpringBootApplication on Spring Boot main application class or @EnableAutoConfiguration. With these annotation Spring Boot will auto-configure serving of static content from /src/resources/static/ or /src/resources/public folders.

Unfortunately our Spring Boot server doesn't serve static files as expected. It happens because of Jersey servlet, which is handling all http requests (/*) and doesn't have clue about static files. If Jersey is only handling some http requests, for e.g. /api/* then this problem will not arise as long as static resources are not kept on /api/* path.

Jersey configuration

We have to make two Jersey configuration changes.

Use Filter to process request

Jersey can handle requests either using Servlet or using Filter. By default, Servlet is used. Make following changes so Filter is used.

File: application.properties

spring.jersey.type=filter

User Filter forward 404

If Jersey doesn't have clue (HTTP status code 404) about the request, it should forward it for further processing.

File: JerseyConfig.java (snippet)

@Component
@ApplicationPath("/")
public class JerseyConfig extends ResourceConfig {

	/*
	 * In constructor we can define Jersey Resources & Other Components
	 */
	public JerseyConfig() {
		
		/*
		 * Jersey will automatically register class with @provider, @Component  by scanning
		 * these packages + nested packages
		 */
		packages("in.geekmj.resource", "in.geekmj.config");
		
		/* CustomTypeParamterConsumeResource auto scanned and register */
		//register(CustomTypeParamterConsumeResource.class);
		register(MatrixUriResource.class);
		register(RequestCookiesResource.class);
		register(RequestHeaderResource.class);
		register(RequestParameterResource.class);
		register(EmployeeResource.class);
		register(HumansResource.class);
		register(HelloWorldResource.class);
		property(ServletProperties.FILTER\_FORWARD\_ON\_404, true);
	}
}

property(ServletProperties.FILTER_FORWARD_ON_404, true); will forward (to other Servlet or filters) all requests that Jersey can't process (404).

Let's say we have a file /src/resources/static/index.html, it is accessible at https://host:port/index.html now.

References

  1. Official Jersey Documentation
  2. Spring Boot reference
  3. Download the Full Project
  4. Follow Project On Github

Comments

Popular posts from this blog

Extend and reuse an existing AirByte destination connector

AirByte is an open-source ELT (Extract, Load, and Transformation) application. It heavily uses containerization for the deployment of its various components. On the local machine, we need docker to run it. AirByte has an impressive list of source and destination connectors available. One of my use case data destinations is the  ClickHouse data warehouse and its destination connector is not yet (2021-12-08) available. As per the documentation, It seems that creating a destination connector is a non-trivial job. It's a great idea to build an open-source ClickHouse destination connector. However, I tried avoiding the temptation to create one because of the required effort. AirByte has a  MySql destination connector available. ClickHouse provides a MySQL connector for access from any MySQL client. We need to configure Clickhouse to give support for the MySQL connector. Accessing ClickHouse from AirByte using its MySQL destination connector looks promising. However, when ...

Understanding Type Checking

A few examples of types in the context of programming language can be integer, float, character, string, array, etc.  When a program executes then data flow between instructions and values of specific types are assigned to a variable after some operation. It's important for the system to verify if the correct types are used as operands in operations. For e.g. In a sum operation, the expectation for operands to be of numeric type. The program's execution should fail in the case there is inconsistency. We can classify programming languages into two categories based as per their ability to cater to type safety: Dynamically Typed Language Statically Typed Language

Setting Clickhouse column data warehouse at Google Cloud Compute Engine VM

I didn't have a Google Cloud account associated with my email, so I signed up for one. It needs a valid Credit Card and mobile number to check if you are human. On successful sign up I get 300$ to spend within 3 months. Creating a free forever Google Cloud Compute Engine VM As per Google Cloud documentation you can have 1 non-preemptible e2-micro VM instance (1GB 2vCPU, 30GB Disk, etc.) per month free forever in some regions with some restrictions. I wanted the following stuff in my VM before I can install Clickhouse on to that: Ubuntu 20.x LTS SSH access from my machine Enabling SSH-based access to Google Compute Engine VM Step 1 Created an ssh private and public key on my mac using the following command ssh-keygen -t rsa -f ~/.ssh/gcloud-ssh-key -C mrityunjay -b 2048 Step 2 Copied the public key from the console using the following command: cat ~/.ssh/gcloud-ssh-key.pub output ssh-rsa <Gibrish :)> mrityunjay Step 3 I went to Google Cloud Console > Co...