LiteSpring is a lightweight, custom-built Java framework inspired by Java Spring Boot framework. This framework aims to provide a minimalistic solution for building REST APIs, handling routing, request mapping, and simple dependency injection, with support for annotations like RestController, GetMapping, and custom method-level annotations such as Authentication.
- RestController & RequestMapping: Simple mapping of HTTP requests for both controllers and controller methods using custom annotations.
- Dynamic URL Path Variables: Support for routes with dynamic URL segments such as /api/products/{id}.
- Custom Annotations: Implement and handle method-level annotations like
- Request Filtering: Manage pre-processing of requests, such as authentication, through filters.
- Annotation-Based Configuration: Lightweight configuration using annotations instead of XML.
- Java 8+
- Apache Tomcat (Embedded)
- Maven (for dependency management)
Clone the repository:
git clone https://github.com/alaminShaheen/litespring
cd litespring
Compile the project using Maven:
mvn clean install
Running the Application To run the application, initialize the embedded Tomcat server and start handling requests:
public static void main(String[] args) {
LiteSpringApplication.run(MainApplication.class, args);
}
Annotations are used to define the behavior of various components, services, and configurations in a declarative manner. They help simplify the setup and management of dependencies, routing, security, and more, without requiring extensive XML or configuration files. Annotations can be used with classes, methods, method parameters and even in attributes. These are the annotations that are currently supported in LiteSpring:
- @Authenticated for securing API endpoints.
- @Autowired to resolve and inject collaborating beans into other beans.
- @Component to detect custom beans automatically.
- @GetMapping to map HTTP GET requests onto specific handler methods.
- @PackageScan to recursively scan all classes within the defined package(s).
- @PathVariable for handling extraction of values from URI path.
- @PostMapping to map HTTP POST requests onto specific handler methods.
- @RequestBody maps the HttpRequest body to a request data transfer object to enable deserializing.
- @RequestMapping to map web requests to Spring Controller methods.
- @RequestParam for handling extraction of values from query string.
- @ResponseBody to serialize response object in JSON and into HttpResponse object.
- @RestController to annotate controller classes.
Define your API endpoints with controller classes using @RestController
and @RequestMapping
annotations. @RestController
annotates the ProductController
class as a controller so that it can receive HTPP requests. The @RequestMapping
annotation sets the base path for the ProductController
as /api/products
.
@RestController
@RequestMapping("/api")
public class ProductController {
@GetMapping("/products")
@ResponseBody
public Product getProducts() {
// Logic to fetch all products
return productService.getProducts();
}
}
Use the @Authentication
annotation to secure specific controller methods.
@RestController
@RequestMapping("/api/secure")
public class SecureController {
@GetMapping("/profile")
@Authentication // Custom authentication check
public User getProfile() {
// Logic to return user profile
}
}
Path variables like /api/products/{id} are automatically extracted and passed as method arguments.
@GetMapping("/{id}")
public Product getProduct(@PathVariable String id) {
// Fetch product by id
}
Add filters to handle request pre-processing, such as validating authentication tokens or for handling logging.
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// Authentication logic here
chain.doFilter(request, response); // Continue if authenticated
}
}
@GetMapping
is used to handle HTTP GET requests. It’s typically used for fetching resources from the server.
@RestController
public class MyController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, World!";
}
}
@PostMapping
is used to handle HTTP POST requests. It’s generally used to submit data to the server.
@RestController
public class MyController {
@PostMapping("/users")
public User createUser(@RequestBody User user) {
// Logic to save a new user
return userService.saveUser(user);
}
}
We can combine @PathVariable
, @RequestParam
, and @RequestBody
with these mappings to handle dynamic URLs and request data.
Below is an example of the @RequestParam
annotation for extracting route parameter for the path /search?name=samsung
@RestController
public class MyController {
@GetMapping("/search")
public List<User> searchUsers(@RequestParam String name) {
// Logic to search users by name
return userService.searchUsers(name);
}
}
Below is an example of the @PathVariable
annotation for extracting the value of id
from the URI path /users/{id}
@RestController
public class MyController {
@GetMapping("/users/{id}")
public User getUserById(@PathVariable String id) {
// Logic to fetch user by id
return userService.getUser(id);
}
}
We can also use the @RequestBody
annotation for sending request body along with HTTP POST request
@RestController
public class MyController {
@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
// Logic to create a user
return new ResponseEntity<>(userService.saveUser(user), HttpStatus.CREATED);
}
}
@Component
is a Spring annotation used to declare a class as a Spring-managed bean. When you annotate a class with @Component
, Spring automatically detects it during classpath scanning and registers it as a bean in the Spring application context.
@Component
public class UserService {
public User getUser(String id) {
// Logic to get user by id
return new User(id, "John Doe");
}
}
Once the UserService class is annotated with @Component, it can be automatically injected into other classes as a dependency using @Autowired
. @Autowired
is used to automatically inject @Component
dependencies into a class. It tells Spring to automatically resolve and inject the required bean into the field.
In the example below, an instance of the UserService
is injected into MyController
.
@RestController
public class MyController {
@Autowired
private UserService userService; // UserService will be automatically injected by Spring
@GetMapping("/users/{id}")
public User getUserById(@PathVariable String id) {
return userService.getUser(id);
}
}