Spring MVC or API Building Notes
Spring MVC or API Building Notes
Model (Chef):
Data ka asli baap! Yeh chef kitchen mein kaam karta hai, khana banata hai,
aur fresh dishes (data) ready karta hai. Bas aapko kya chahiye yeh bataana
padta hai (input).
View (Waiter/Presentation):
Chef ke haathon se bana khana (data) ko plate mein sajake customer (user)
ke saamne laata hai. Yeh sirf dikhane ka kaam karta hai, khana (data) ke
taste pe control nahi hai.
Controller (Manager):
Manager aapki order (request) sunta hai aur usko chef (Model) aur waiter
(View) ke beech set kar deta hai.
Manager decide karta hai ki kaunsi order kahan jayegi aur kaise wapas
customer ko milegi.
Yeh banda browser kholta hai aur "Menu mein kya hai?" poochta hai.
2. DispatcherServlet (Receptionist):
Aapki request pehle yahan aayegi. Yeh decide karega ki aapki request
kahan forward karni hai.
3. Controller (Manager):
Yeh aapki request Model (Chef) tak bhejta hai aur chef se output lekar
waiter ko deta hai.
4. Model (Chef):
Data ka kaam karta hai: database se uthaata hai, process karta hai, aur
fresh output Controller ko deta hai.
5. View (Waiter):
Yeh user ke liye data ko style karke dikhata hai (HTML, JSON, JSP,
etc.).
6. Response (Khana):
Aakhir mein user ko result milta hai, ekdum properly serve kiya hua.
Flow:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example")
Controllers
Controllers handle the logic for processing user input and returning the
appropriate view or data.
Example:
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "index"; // Returns view (index.jsp)
}
}
Handling Requests
: A combination of
@RestController @Controller and @ResponseBody , used for
REST APIs returning JSON/XML.
Example:
Model: Represents the data and the business logic of the application. It
interacts with the database and other data sources.
1. Open your IDE (like IntelliJ IDEA, Eclipse, or STS) and create a new Maven
project.
<groupId>com.example</groupId>
<artifactId>SpringMVCDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.13</version>
</dependency>
<build>
Explanation:
c. Directory Structure:
bashCopy code
src/
├── main/
│ ├── java/
│ │ └── com/example/SpringMVCDemo/
│ │ └── config/
│ │ └── controller/
│ ├── resources/
│ └── webapp/
│ ├── WEB-INF/
│ │ └── web.xml
│ │ └── views/
│ │ └── hello.jsp
2. Configure web.xml
web.xml is the deployment descriptor for your application. Here we configure
the DispatcherServlet .
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan
ce"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/ja
vaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_
1.xsd"
version="3.1">
<display-name>SpringMVCDemo</display-name>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Explanation:
<beans xmlns="http://www.springframework.org/schema/beans"
</beans>
Explanation:
javaCopy code
package com.example.SpringMVCDemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestPara
m;
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello(@RequestParam(name="name", requi
red=false, defaultValue="World") String name, Model model)
{
model.addAttribute("name", name);
return "hello"; // Logical view name
}
}
Explanation:
to this method.
The method takes a name parameter from the request and adds it to the
model, which is passed to the view.
Explanation:
This JSP file displays a simple message using the name attribute passed
from the controller.
1. Open your IDE (like IntelliJ IDEA, Eclipse, or STS) and create a new Maven
project.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan
ce"
xsi:schemaLocation="http://maven.apache.org/POM/4.
0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>SpringMVCJavaConfigDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.13</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissi
ngWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Explanation:
c. Directory Structure:
Ensure your project directory structure looks like this:
bashCopy code
src/
├── main/
2. Java-Based Configuration
a. Create the WebInitializer Class:
This class will replace the web.xml and configure the DispatcherServlet .
javaCopy code
package com.example.SpringMVCJavaConfigDemo.config;
import org.springframework.web.servlet.support.AbstractAnno
tationConfigDispatcherServletInitializer;
@Override
protected Class<?>[] getRootConfigClasses() {
return null; // No root configuration in this case
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
Explanation:
extends AbstractAnnotationConfigDispatcherServletInitializer ,
WebInitializer
javaCopy code
package com.example.SpringMVCJavaConfigDemo.config;
import org.springframework.context.annotation.ComponentSca
n;
import org.springframework.context.annotation.Configuratio
n;
import org.springframework.web.servlet.config.annotation.En
ableWebMvc;
import org.springframework.web.servlet.config.annotation.Vi
ewResolverRegistry;
import org.springframework.web.servlet.config.annotation.We
bMvcConfigurer;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.SpringMVCJavaCon
figDemo")
public class WebConfig implements WebMvcConfigurer {
Explanation:
(controllers, etc.).
javaCopy code
package com.example.SpringMVCJavaConfigDemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestPara
m;
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello(@RequestParam(name="name", requi
Explanation:
to this method.
The method takes a name parameter from the request and adds it to the
model, which is passed to the view.
jspCopy code
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix
="c" %>
<!DOCTYPE html>
<html>
<head>
<title>Hello Page</title>
</head>
<body>
<h1>Hello, ${name}!</h1>
</body>
</html>
Explanation:
You should see a message like "Hello, YourName!" displayed on the page.
1. No web.xml Required
Spring Boot Auto-Configuration: Spring Boot automatically sets up the
DispatcherServlet and maps it to the root URL ( / ) without requiring a web.xml
javaCopy code
@SpringBootApplication
public class SpringBootMvcApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMvcApplication.c
lass, args);
}
}
xmlCopy code
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
xmlCopy code
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
8. Production-Ready Features
Monitoring and Management: Spring Boot provides production-ready
features out of the box, such as health checks, metrics, and application
monitoring via the spring-boot-starter-actuator .
javaCopy code
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApp
lication;
@SpringBootApplication
public class SpringBootMvcApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMvcApplication.clas
s, args);
}
3. A Simple Controller:
javaCopy code
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestPara
m;
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello(@RequestParam(name="name", requi
red=false, defaultValue="World") String name, Model model)
{
model.addAttribute("name", name);
return "hello";
}
}
JSP: src/main/webapp/WEB-INF/jsp/hello.jsp
<html>
<body>
<h1>Hello, ${name}!</h1>
</body>
</html>
1. @Controller
Purpose:
Example:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMappin
g;
@Controller
public class MyController {
@GetMapping("/welcome")
public String welcome(Model model) {
model.addAttribute("message", "Welcome to Spring
MVC!");
return "welcome"; // This refers to a view named
"welcome"
}
}
2. @RequestMapping
Purpose:
It can be applied at both the class and method levels to specify the URL
patterns and HTTP methods.
Example:
port org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMa
pping;
import org.springframework.web.bind.annotation.RequestMe
thod;
@Controller
@RequestMapping("/api")
public class ApiController {
Example:
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.PostMappi
ng;
import org.springframework.web.bind.annotation.RestContr
oller;
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable("id") Long id) {
return "Fetching user with ID: " + id;
}
@PostMapping
public String createUser() {
return "Creating a new user";
}
}
4. @PathVariable
Purpose:
Example:
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.PathVaria
ble;
import org.springframework.web.bind.annotation.RestContr
oller;
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/{orderId}")
public String getOrder(@PathVariable("orderId") Stri
ng orderId) {
return "Order ID: " + orderId;
}
}
5. @RequestParam
Purpose:
in the request.
Example:
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.RequestPa
@RestController
@RequestMapping("/search")
public class SearchController {
@GetMapping
public String search(@RequestParam("q") String quer
y) {
return "Searching for: " + query;
}
}
method parameter.
Spring .
6. @RequestBody
Purpose:
Example:
import org.springframework.web.bind.annotation.PostMappi
ng;
import org.springframework.web.bind.annotation.RequestBo
dy;
import org.springframework.web.bind.annotation.RestContr
oller;
@RestController
@RequestMapping("/products")
@PostMapping
public String addProduct(@RequestBody Product produc
t) {
return "Product added: " + product.getName();
}
}
7. @ResponseBody
Purpose:
Example:
javaCopy code
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.ResponseB
ody;
import org.springframework.web.bind.annotation.RestContr
oller;
@RestController
@RequestMapping("/status")
public class StatusController {
@GetMapping
@ResponseBody
public String status() {
return "Application is running";
}
8. @RestController
Purpose:
Example:
javaCopy code
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.RestContr
oller;
@RestController
@RequestMapping("/api")
public class ApiRestController {
@GetMapping("/hello")
public String sayHello() {
return "Hello from REST API";
}
}
9. @RequestHeader
Purpose:
javaCopy code
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.RequestHe
ader;
import org.springframework.web.bind.annotation.RestContr
oller;
@RestController
@RequestMapping("/headers")
public class HeaderController {
@GetMapping
public String getHeader(@RequestHeader("User-Agent")
String userAgent) {
return "User-Agent: " + userAgent;
}
}
10. @ModelAttribute
Purpose:
Example:
javaCopy code
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMappin
g;
import org.springframework.web.bind.annotation.ModelAttr
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/form")
public String userForm(Model model) {
model.addAttribute("user", new User());
return "userForm";
}
@PostMapping("/save")
public String saveUser(@ModelAttribute User user) {
// Save user to database
return "redirect:/user/success";
}
}
In this example, @ModelAttribute binds the form data to a User object and
adds it to the model.
11. @SessionAttributes
Purpose:
Example:
javaCopy code
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttr
ibute;
@Controller
@RequestMapping("/checkout")
@SessionAttributes("cart")
public class CheckoutController {
@ModelAttribute("cart")
public Cart setupCart() {
return new Cart();
}
@RequestMapping("/review")
public String reviewCart(@ModelAttribute("cart") Car
t cart, Model model) {
// Process cart
return "reviewCart";
}
}
12. @ExceptionHandler
Purpose:
Example:
javaCopy code
import org.springframework.web.bind.annotation.Controlle
rAdvice;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleResourceNotFoundException() {
return "error/404";
}
}
package com.example.demo.model;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
Explanation:
The fields are validated to ensure that they meet specific constraints,
such as not being empty, having a valid email format, and adhering to
specific size limits.
javaCopy code
package com.example.demo.controller;
import com.example.demo.model.User;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestControll
er;
import java.util.HashMap;
import java.util.Map;
@RestController
public class UserController {
@PostMapping("/users")
public ResponseEntity<Object> createUser(@Valid @Reques
tBody User user, BindingResult result) {
if (result.hasErrors()) {
Explanation:
response.
javaCopy code
package com.example.demo.exception;
import jakarta.validation.ConstraintViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidE
xception;
import org.springframework.web.bind.annotation.ControllerAd
vice;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.clas
s)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Map<String, String>> handleValida
tionExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((erro
r) -> {
String fieldName = ((FieldError) error).getFiel
d();
String errorMessage = error.getDefaultMessage
();
errors.put(fieldName, errorMessage);
});
return new ResponseEntity<>(errors, HttpStatus.BAD_
REQUEST);
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Map<String, String>> handleConstr
aintViolationExceptions(ConstraintViolationException ex) {
Map<String, String> errors = new HashMap<>();
ex.getConstraintViolations().forEach(violation -> {
String fieldName = violation.getPropertyPath().
toString();
String errorMessage = violation.getMessage();
Explanation:
javaCopy code
package com.example.demo.validation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface ValidPassword {
package com.example.demo.validation;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
@Override
public boolean isValid(String value, ConstraintValidato
rContext context) {
if (value == null) {
return false;
}
return value.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*
\\d).+$");
}
}
package com.example.demo.validation;
import jakarta.validation.ConstraintValidator;
@Override
public void initialize(ValidPassword constraintAnnotation
// Access the message from the annotation
this.message = constraintAnnotation.message();
}
@Override
public boolean isValid(String value, ConstraintValidatorCo
if (value == null || !value.matches("^(?=.*[a-z])(?=.
// Customize the error message in the validation c
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(messa
.addConstraintViolation();
return false;
}
return true;
}
}
javaCopy code
package com.example.demo.model;
import com.example.demo.validation.ValidPassword;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
@ValidPassword
private String password;
javaCopy code
package com.example.demo.validation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
Explanation:
javaCopy code
package com.example.demo.validation;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.List;
@Override
public boolean isValid(MultipartFile value, ConstraintV
alidatorContext context) {
if (value == null || value.isEmpty()) {
return true; // Consider null or empty file as
valid. Handle required validation separately.
}
Explanation:
The isValid method checks whether the uploaded file's content type
matches one of the allowed types.
javaCopy code
package com.example.demo.model;
import com.example.demo.validation.ValidImage;
import org.springframework.web.multipart.MultipartFile;
Explanation:
javaCopy code
package com.example.demo.controller;
import com.example.demo.model.ImageUploadRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestControll
er;
import org.springframework.web.bind.annotation.ModelAttribu
te;
import org.springframework.web.multipart.MultipartFile;
import jakarta.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@RestController
public class ImageUploadController {
@PostMapping("/uploadImage")
public ResponseEntity<Object> uploadImage(@Valid @Model
Attribute ImageUploadRequest request, BindingResult result)
{
if (result.hasErrors()) {
Map<String, String> errors = new HashMap<>();
result.getFieldErrors().forEach(error -> error
s.put(error.getField(), error.getDefaultMessage()));
return new ResponseEntity<>(errors, HttpStatus.
BAD_REQUEST);
ModelAndView modelAndView) :
Called after the view has been rendered and the request is complete.
3. Creating an Interceptor
Let's create a simple logging interceptor that logs request details before and
after a controller is executed.
javaCopy code
package com.example.demo.interceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Override
public boolean preHandle(HttpServletRequest request, Ht
tpServletResponse response, Object handler) throws Exceptio
n {
System.out.println("Pre Handle method is Calling: "
+ request.getRequestURI());
return true; // Continue with the next interceptor
or the controller method
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("Request and Response is complet
ed: " + request.getRequestURI());
}
}
Explanation:
executed.
postHandle : Logs after the controller method has executed but before the
view is rendered.
afterCompletion : Logs after the request has been fully processed and the
response is completed.
javaCopy code
package com.example.demo.config;
import com.example.demo.interceptor.LoggingInterceptor;
import org.springframework.context.annotation.Configuratio
n;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registr
y) {
registry.addInterceptor(new LoggingInterceptor())
.addPathPatterns("/**") // Intercept all r
equests
.excludePathPatterns("/api/ignore/**"); //
Exclude certain paths
}
}
Explanation:
4o
how to register in lasted spring boot usign filterchain
ChatGPT
In the latest versions of Spring Boot (particularly with Spring Security and
Spring Web), the registration of interceptors and filters has evolved, particularly
with the introduction of SecurityFilterChain and the use of Filter for handling
security-related tasks. However, if you want to register a custom interceptor in
the context of a Spring Boot application, the approach remains straightforward.
In the latest Spring Boot, you still use WebMvcConfigurer to register your
interceptors.
javaCopy code
package com.example.demo.config;
import com.example.demo.interceptor.LoggingInterceptor;
import org.springframework.context.annotation.Configuratio
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registr
y) {
registry.addInterceptor(new LoggingInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/api/ignore/**");
}
}
javaCopy code
package com.example.demo.filter;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
@Override
public void init(FilterConfig filterConfig) throws Serv
letException {
// Initialization logic if needed
}
@Override
public void doFilter(ServletRequest request, ServletRes
ponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletReques
t) request;
HttpServletResponse httpResponse = (HttpServletResp
onse) response;
@Override
public void destroy() {
// Cleanup logic if needed
}
}
javaCopy code
package com.example.demo.config;
import com.example.demo.filter.CustomSecurityFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuratio
n;
import org.springframework.security.config.annotation.web.b
uilders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChai
n;
import org.springframework.security.web.authentication.User
namePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecu
rity http) throws Exception {
http
// Add your custom filter before/after specific
filters
.addFilterBefore(new CustomSecurityFilter(), Us
ernamePasswordAuthenticationFilter.class)
// Add your security configurations
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/public/**").permitAl
l()
.anyRequest().authenticated()
)
.formLogin()
.and()
return http.build();
}
}
Explanation:
File Upload
File upload in Spring Boot can be handled easily using Spring MVC's
MultipartFile interface. This allows you to upload files from clients to your
server, where you can process or store them.
xmlCopy code
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Example in application.properties :
propertiesCopy code
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB
javaCopy code
package com.example.demo.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPara
m;
import org.springframework.web.bind.annotation.RestControll
er;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@RestController
public class FileUploadController {
try {
// Get the file and save it to the local filesy
stem
String fileName = file.getOriginalFilename();
File destinationFile = new File(UPLOAD_DIR + fi
leName);
file.transferTo(destinationFile);
Explanation:
javaCopy code
import javax.annotation.PostConstruct;
@PostConstruct
public void init() {
File uploadDir = new File(UPLOAD_DIR);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
}
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.io.File;
@Configuration
public class FileUploadConfig {
@PostConstruct
public void init() {
File uploadDir = new File(UPLOAD_DIR);
if (!uploadDir.exists()) {
boolean created = uploadDir.mkdir();
if (created) {
System.out.println("Upload directory created:
} else {
System.err.println("Failed to create upload di
javaCopy code
@PostMapping("/uploadMultiple")
public ResponseEntity<String> uploadMultipleFiles(@RequestP
aram("files") MultipartFile[] files) {
StringBuilder resultMessage = new StringBuilder();
try {
String fileName = file.getOriginalFilename();
File destinationFile = new File(UPLOAD_DIR + fi
leName);
file.transferTo(destinationFile);
resultMessage.append("File uploaded successfull
y: ").append(fileName).append("\n");
} catch (IOException e) {
e.printStackTrace();
resultMessage.append("Failed to upload file:
").append(file.getOriginalFilename()).append("\n");
}
Explanation:
The method iterates over each file and processes them as before.
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam("fil
e") MultipartFile file) {
if (file.isEmpty()) {
return new ResponseEntity<>("Please select a file t
o upload.", HttpStatus.BAD_REQUEST);
}
try {
// Save the file
String fileName = file.getOriginalFilename();
File destinationFile = new File(UPLOAD_DIR + fileNa
me);
file.transferTo(destinationFile);
Rest APIS
REST (Representational State Transfer): An architectural style for
designing networked applications, relying on a stateless, client-server
communication protocol—usually HTTP.
HTTP Methods:
REST APIs commonly use HTTP methods to interact with resources:
GET: Retrieve data from the server (e.g., fetch a list of users).
POST: Create a new resource on the server (e.g., create a new user).
PUT: Update an existing resource on the server (e.g., update user details).
Use nouns to represent resources, not verbs (e.g., /users rather than
/getUsers ).
Versioning:
Version your API using the URL (e.g., /v1/users ) or using headers.
Statelessness:
Each API call should contain all the information the server needs to
fulfill the request.
The server does not store any session information between requests.
Use appropriate status codes to indicate the result of the API request:
403 Forbidden: The request was valid, but the server is refusing
action.
GET /api/books
Response:
[
{
"id": 1,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_year": 1925
},
{
"id": 2,
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"published_year": 1960
}
]
This request fetches a list of all the books available in the library.
GET /api/books/1
{
"id": 1,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_year": 1925
}
POST /api/books
Content-Type: application/json
{
"title": "1984",
"author": "George Orwell",
"published_year": 1949
}
Response:
{
"id": 3,
"title": "1984",
"author": "George Orwell",
"published_year": 1949
This request creates a new book in the library and returns the details of the
newly created book.
PUT /api/books/1
Content-Type: application/json
{
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_year": 1926
}
Response:
jsonCopy code
{
"id": 1,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_year": 1926
}
DELETE /api/books/1
{
"message": "Book deleted successfully"
}
Nested URLs: These represent the relationship between the parent and
child resources. For example, /categories/{categoryId}/products refers to all
products within a specific category.
GET /api/categories
Response:
[
{
"id": 1,
GET /api/categories/1/products
Response:
[
{
"id": 101,
"name": "Smartphone",
"price": 699.99
},
{
"id": 102,
"name": "Laptop",
"price": 1299.99
}
]
GET /api/categories/1/products/101
Response:
jsonCopy code
{
"id": 101,
"name": "Smartphone",
"price": 699.99,
"description": "Latest model smartphone with advanced f
eatures."
}
POST /api/categories/1/products
Content-Type: application/json
{
"name": "Tablet",
"price": 499.99,
"description": "A powerful tablet with a sleek design."
}
Response:
PUT /api/categories/1/products/103
Content-Type: application/json
{
"name": "Tablet",
"price": 549.99,
"description": "Updated tablet with enhanced features."
}
Response:
{
"id": 103,
"name": "Tablet",
"price": 549.99,
"description": "Updated tablet with enhanced features."
}
Response:
{
"message": "Product deleted successfully"
}