Skip to content

Commit

Permalink
Feature/blzt 83 (#84)
Browse files Browse the repository at this point in the history
* [BLZT-10,11] added tests and started java doc

* [BLZT-10,11] added test for MissingBringServletImplException when RestController does not implement BringServlet interface

* [BLZT-10,11] added java docs except DispatcherServlet and tests

* [BLZT-10,11] fixed lower case package name

* [BLZT-10,11] fixed build error

* [BLZT-10,11] fixed build error

* [BLZT-10,11] refactoring and java docs for DispatcherServlet

* [BLZT-10,11] markdown for web package

* [BLZT-10,11] new markdowns for web package

* [BLZT-83] ResponseEntity implementation, java doc, markdown

* [BLZT-83] small improvements

* [BLZT-83] BringServlet.md

* [BLZT-83] small improvements
  • Loading branch information
romanovosad87 authored Nov 29, 2023
1 parent d48d7e4 commit eec6ead
Show file tree
Hide file tree
Showing 42 changed files with 498 additions and 94 deletions.
7 changes: 4 additions & 3 deletions Web.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@

- [Embedded Server](features/web/server/TomcatWebServer.md): This is server integrated or bundled within an application or system. It allows the application to run without needing an external server. The server is often lightweight and designed for specific purposes or frameworks.
- [Dispatcher Servlet](features/web/servlet/DispatcherServlet.md): In the context of Java-based web applications, a Dispatcher Servlet is the front controller in the Bring framework's MVC architecture. It receives incoming requests and directs them to the appropriate resources (controllers, views, etc.) for processing.
- REST API: Representational State Transfer (REST) API is a set of rules and conventions for building web services that enable communication between different systems on the internet. It uses HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on resources and typically returns responses in JSON or XML (//TODO ) format.
- [REST API](features/web/servlet/RestApi.md): Representational State Transfer (REST) API is a set of rules and conventions for building web services that enable communication between different systems on the internet. It uses HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on resources and typically returns responses in JSON format.
- [Static Content Serving](features/web/servlet/StaticResourceController.md): This refers to the process of serving static files (HTML, CSS, JavaScript, images, etc.) directly to clients without any processing or modification by the server. This content is typically served as-is from the server's file system or a specified directory.
- [Exception handler](features/web/servlet/JsonExceptionHandler.md): This component specializes in managing exceptions by intercepting and customizing error responses in JSON format. It extends ErrorReportValve to provide tailored error handling within a Servlet container.


- addition items:
- The code supports the generation of a random port based on the key ${random.port}. When this key is encountered as the value for a property, it is replaced with a randomly generated port number within the specified range. The range for the random port generation is defined by the constants START_PORT_RANGE and END_PORT_RANGE, which are set to 8000 and 9000, respectively. This feature allows dynamic allocation of ports, which can be useful in scenarios where a unique port is needed, and the actual port number is not predetermined but instead generated at runtime.
- The `ValuePropertiesPostProcessor` class supports dynamic profile configuration using VM parameters. Set the active profile with the `-Dbring.profiles.active=dev` parameter during application launch. This enables the class to resolve profile-specific properties and apply them to the `DefaultBringBeanFactory`, allowing for adaptable configuration based on the specified profile. Additionally, the active profiles influence the loading of different `application.properties` files. For example, with an active profile of "dev," the class will load properties from `application-dev.properties`. This mechanism allows for customized property sets tailored to specific application environme
- annotation:
- The `ValuePropertiesPostProcessor` class supports dynamic profile configuration using VM parameters. Set the active profile with the `-Dbring.profiles.active=dev` parameter during application launch. This enables the class to resolve profile-specific properties and apply them to the `DefaultBringBeanFactory`, allowing for adaptable configuration based on the specified profile. Additionally, the active profiles influence the loading of different `application.properties` files. For example, with an active profile of "dev," the class will load properties from `application-dev.properties`. This mechanism allows for customized property sets tailored to specific application environments.

- annotations:
- [@GetMapping](features/web/servlet/annotation/GetMapping.md)
- [@Controller](features/web/servlet/annotation/Controller.md)
- [@RestController](features/web/servlet/annotation/RestController.md)
Expand Down
21 changes: 21 additions & 0 deletions features/web/servlet/BringServlet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# BringServlet Interface Documentation

The `BringServlet` interface is a marker interface used to identify classes that need to be implemented for use as REST controllers within the Bring framework. Classes implementing this interface play a significant role in the configuration and setup of the REST controller context.

## Overview

The primary purpose of the `BringServlet` interface is to act as a marker, signaling to the system that a particular class should be recognized as a servlet within the Bring framework. It does not mandate the addition of any specific methods, serving solely as an indicator for classes that should be included in the REST controller context setup.

## Usage

To make use of the `BringServlet` interface, a class needs to implement it:

```java
@RestController
public class MyRestController implements BringServlet {
// REST controller logic and methods
}
```

### See Also
[RestController](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/RestController.md)
7 changes: 4 additions & 3 deletions features/web/servlet/DispatcherServlet.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ The `DispatcherServlet` class extends `FrameworkServlet` and serves as the centr

## Key Components

- `responseAnnotationResolver`: List of response annotation resolvers for handling custom annotations on controller methods.
- `objectMapper`: Object mapper for converting between JSON and Java objects.

## Methods
Expand All @@ -36,11 +35,13 @@ Invokes the controller method with the provided arguments and handles the result

### `performResponse(RestControllerProcessResult processResult, HttpServletResponse resp)`

Handles the response generated by a controller method. Checks for custom response annotations using registered `ResponseAnnotationResolver`s, applies the annotations if found, and then writes the response to the provided `HttpServletResponse`.
Handles the response generated by a controller method. Checks if the response is an instance of `ResponseEntity`. If it is, processes the response entity, including HTTP status and headers. Writes the final response (including possible modifications) to the provided `HttpServletResponse`.

### Other Utility Methods

- `checkIfUrlIsStatic(String requestPath, String paramPath)`: Checks if the provided request path and parameter path match a static URL pattern.
- `checkIfPathVariableAnnotationIsPresent(Parameter[] parameters)`: Checks if any of the given parameters are annotated with `PathVariable`.
- `prepareArgs(HttpServletRequest req, HttpServletResponse resp, String requestPath, Method method)`: Prepares the arguments for invoking a controller method.
- Methods for extracting values of path variables, request parameters, request body, and request headers.
- `processResponseEntity(HttpServletResponse resp, ResponseEntity<?> entity)`: Processes a `ResponseEntity` object, setting the HTTP status code and headers in the provided `HttpServletResponse`.
- `processResponseStatusAnnotation(RestControllerProcessResult processResult, HttpServletResponse resp)`: Processes the `ResponseStatus` annotation, if present, for a controller method. Sets the HTTP status code of the provided `HttpServletResponse` based on the annotation value.
- Methods for extracting values of path variables, request parameters, request body and request headers.
50 changes: 50 additions & 0 deletions features/web/servlet/ResponseEntity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ResponseEntity Class Documentation

The `ResponseEntity` class represents an HTTP response entity in the context of a Spring application. It encapsulates the response body, headers, and HTTP status, providing flexibility and control over the structure of the API response.

## Overview

The primary purpose of `ResponseEntity` is to allow developers to customize the HTTP response sent from a controller method. It becomes particularly useful when working in conjunction with the `@ResponseStatus` annotation.

**Note:** When both `ResponseEntity` and `@ResponseStatus` are used in a controller method, the HTTP status from `ResponseEntity` takes precedence over the one specified by `@ResponseStatus`.

## Generic Type Parameter

The class is generic, allowing the specification of the type of the response body using the type parameter `<T>`.

```java
public class ResponseEntity<T> {
// class implementation
}
```

### Constructors

1. Full Constructor
```
public ResponseEntity(T body, HttpHeaders headers, HttpStatus httpStatus)
```
Constructs a new ResponseEntity with the given response body, headers, and HTTP status.

2. Constructor with Body and Status
```
public ResponseEntity(T body, HttpStatus httpStatus)
```
Constructs a new ResponseEntity with the given response body and HTTP status. Headers are set to null.

3. Constructor with Headers and Status
```
public ResponseEntity(HttpHeaders headers, HttpStatus httpStatus)
```
Constructs a new ResponseEntity with the given headers and HTTP status. The response body is set to null.

### Methods

#### `getHeaders()`
Gets the headers included in the response.

#### `getBody()`
Gets the body of the response.

#### `getHttpStatus()`
Gets the HTTP status of the response.
145 changes: 145 additions & 0 deletions features/web/servlet/RestApi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Building REST API with Bring: A Quick Guide

## Introduction

When building a RESTful API using the Bring framework, the annotations like [`@RestController`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/RestController.md),
[`@RequestMapping`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/PostMapping.md),
[`@GetMapping`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/GetMapping.md),
[`@PathVariable`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/PathVariable.md),
[`@RequstBody`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/RequestBody.md) and others can be used.
These annotations simplify the development process and ensure a standardized approach to creating web services.
[`ResponseEntity`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/ResponseEntity.md) allows you to customize the HTTP response, including status codes, headers, and the response body.
This guide will walk you through the essential steps to set up a REST controller.

**1. Create a REST Controller**

To get started, create a class and annotate it with
[`@RestController`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/RestController.md).
This annotation indicates that the class will handle HTTP requests and produce HTTP responses for a RESTful API.
The class should implement marker interface
[`BringServlet`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/BringServlet.md) to be recognized as controller by the framework and setup of the REST controller context.
The [`@RequestMapping`](https://github.com/YevgenDemoTestOrganization/bring/blob/d1df5bd13e15033caad3f012bc3ef5c3be780c1f/features/web/servlet/annotation/RequestMapping.md) annotation can be utilized to define the base path for all endpoints in the controller (`/api`).

**Example:**
```java
@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {
// REST controller logic and methods
}
```

**2. Define Endpoints with @GetMapping**

Use the @GetMapping annotation to define methods that handle HTTP GET requests. These methods will serve as endpoints for retrieving information.
When you need to extract values from the URI use the `@PathVariable` or `@RequestParam` annotation.

**Example:**
```java
@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {

@GetMapping(path = "/resource/{id}")
public ResponseEntity<Resource> getResource(@PathVariable Long id) {
// Your implementation logic here
}
}
```
**Example:**
```java
@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {

@GetMapping(path = "/resource")
public ResponseEntity<Resource> getResource(@RequestParam Long id, @RequestParam String name) {
// Your implementation logic here
}
}
```

**3. Define Endpoints with @PutMapping**

Use the `@PutMapping` annotation to define methods that handle HTTP PUT requests. These methods will serve as endpoints for updating existing resources.

**Example:**
```java
@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {

@PutMapping(path = "/resource/{id}")
public ResponseEntity<String> updateResource(@PathVariable Long id,
@RequestBody UserDto dto) {
// Your implementation logic here
}
}
```
Here, the updateResource method handles `PUT` requests to `/api/resource/{id}`.
The `@PathVariable` annotation extracts the id from the URI and `@RequestBody` is used to capture the data sent in the request body.

**4. Define Endpoints with @RequestHeader**

Utilize the @RequestHeader annotation to extract values from HTTP headers in your endpoint methods.

**Example:**
```java
@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {

@PostMapping(path = "/resource")
public ResponseEntity<String> resourceHeaders(@RequestHeader("Authorization") String authToken) {
// Your implementation logic here
}
}
```
**5. Use ResponseEntity for Flexible Responses**

`ResponseEntity` allows to customize the HTTP response, including status codes, headers and the response body.

**Example:**

```java
import java.util.ResourceBundle;

@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {

@PostMapping(path = "/resource")
public ResponseEntity<Resource> saveResource(@RequestBody ResourceDto dto) {
// Save resource to DB
Resource resource = saveToDB(dto);

// Set custom headers
HttpHeaders headers = new HttpHeaders();
headers.set("Custom", "Value");

// return instance of ResponseEntity
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}
}
```

**6. Define Endpoints with @ResponseStatus**

Utilize the @ResponseStatus annotation to define the desired HTTP response status code for specific methods.

**Example:**
```java
@RestController
@RequestMapping(path = "/api")
public class MyRestController implements BringServlet {

@PutMapping(path = "/resource/{id}")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public ResponseEntity<String> updateResource(@PathVariable Long id,
@RequestBody UserDto dto) {
// Your implementation logic here
}
}
```
**NOTE:** When both `ResponseEntity` and `@ResponseStatus` are used in a controller method,
the HTTP status from `ResponseEntity` takes precedence over the one specified by `@ResponseStatus`.
5 changes: 4 additions & 1 deletion features/web/servlet/annotation/DeleteMapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ This annotation is used to declare a method as a handler for HTTP `DELETE` reque
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@DeleteMapping(path = "/resource/{id}")
public void deleteResource(@PathVariable Long id) {
// Your implementation logic here
}
}
```

### See Also
[ResponseEntity](https://github.com/YevgenDemoTestOrganization/bring/blob/09aafc6d471c5f793eea58cf8793c68443ec14e8/features/web/servlet/ResponseEntity.md)
8 changes: 5 additions & 3 deletions features/web/servlet/annotation/GetMapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ This annotation is used to declare a method as a handler for HTTP `GET` requests
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@GetMapping(path = "/resource/{id}")
public Resource getResource(@PathVariable Long id) {
public ResponseEntity<Resource> getResource(@PathVariable Long id) {
// Your implementation logic here
}
}
```
```
### See Also
[ResponseEntity](https://github.com/YevgenDemoTestOrganization/bring/blob/09aafc6d471c5f793eea58cf8793c68443ec14e8/features/web/servlet/ResponseEntity.md)
6 changes: 4 additions & 2 deletions features/web/servlet/annotation/PatchMapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ This annotation is used to declare a method as a handler for HTTP `PATCH` reques
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@PatchMapping(path = "/resource")
public void patchResource(@RequestBody UserDto dto) {
// Your implementation logic here
}
}
```
```
### See Also
[ResponseEntity](https://github.com/YevgenDemoTestOrganization/bring/blob/09aafc6d471c5f793eea58cf8793c68443ec14e8/features/web/servlet/ResponseEntity.md)
4 changes: 2 additions & 2 deletions features/web/servlet/annotation/PathVariable.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ This annotation is used to declare that a method parameter should be bound to a
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@GetMapping(path = "/resource/{id}")
public Resource getResource(@PathVariable Long id) {
public ResponseEntity<Resource> getResource(@PathVariable Long id) {
// Your implementation logic here
}
}
Expand Down
9 changes: 6 additions & 3 deletions features/web/servlet/annotation/PostMapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ This annotation is used to declare a method as a handler for HTTP `POST` request
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@PostMapping(path = "/resource")
public void postResource(@RequestBody UserDto dto) {
public void saveResource(@RequestBody UserDto dto) {
// Your implementation logic here
}
}
```
```

### See Also
[ResponseEntity](https://github.com/YevgenDemoTestOrganization/bring/blob/09aafc6d471c5f793eea58cf8793c68443ec14e8/features/web/servlet/ResponseEntity.md)
12 changes: 8 additions & 4 deletions features/web/servlet/annotation/PutMapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ This annotation is used to declare a method as a handler for HTTP `PUT` requests
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@PutMapping(path = "/resource")
public void putResource(@RequestBody UserDto dto) {
@PutMapping(path = "/resource/{id}")
public void updateResource(@PathVariable Long id,
@RequestBody UserDto dto) {
// Your implementation logic here
}
}
```
```

### See Also
[ResponseEntity](https://github.com/YevgenDemoTestOrganization/bring/blob/09aafc6d471c5f793eea58cf8793c68443ec14e8/features/web/servlet/ResponseEntity.md)
2 changes: 1 addition & 1 deletion features/web/servlet/annotation/RequestBody.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This annotation does not have additional attributes when applied to a method par
**Usage Example:**
```java
@RestController
public class MyController implements BringServlet {
public class MyRestController implements BringServlet {

@PostMapping(path = "/resource")
public void postResource(@RequestBody UserDto dto) {
Expand Down
Loading

0 comments on commit eec6ead

Please sign in to comment.