๐ช The Web Layer: Your Appโs Front Door
Imagine your Spring Boot application is a fancy hotel. Guests (HTTP requests) arrive at the front entrance, but before they reach their room (your controller), they pass through security, get their luggage handled, and receive directions. Thatโs exactly what the Web Layer does!
๐ฆ File Upload Handling: The Luggage Service
Think of file uploads like guests bringing luggage to a hotel. The bellhop (Springโs MultipartFile) takes it, checks it, and stores it safely.
How It Works
When someone uploads a file to your app, Spring catches it like a baseball glove catches a ball:
@PostMapping("/upload")
public String handleUpload(
@RequestParam("file")
MultipartFile file) {
// Get file name
String name = file.getOriginalFilename();
// Get file size
long size = file.getSize();
// Save the file
file.transferTo(new File("/uploads/" + name));
return "Uploaded: " + name;
}
Setting Limits
You donโt want someone bringing a truck-sized suitcase! Set limits in application.properties:
# Max file size: 10MB
spring.servlet.multipart.max-file-size=10MB
# Max request size: 50MB
spring.servlet.multipart.max-request-size=50MB
Quick Flow
graph TD A["๐ค User Uploads File"] --> B["๐งณ MultipartFile Catches It"] B --> C{๐ Size OK?} C -->|Yes| D["๐พ Save to Disk/Cloud"] C -->|No| E["โ Reject - Too Big!"] D --> F["โ Success Response"]
Key Points:
MultipartFile= Springโs way to handle uploaded files- Always validate file size and type
- Never trust the filename - sanitize it!
๐ผ๏ธ Static Resources: The Hotelโs Decorations
Static resources are like the paintings, carpets, and furniture in our hotel - they donโt change and are always there. These include CSS files, JavaScript, images, and fonts.
Where Spring Looks
By default, Spring Boot serves static files from these locations:
| Location | Priority |
|---|---|
/META-INF/resources/ |
1st |
/resources/ |
2nd |
/static/ |
3rd โญ Most common |
/public/ |
4th |
Example Structure
src/main/resources/
โโโ static/
โโโ css/
โ โโโ style.css
โโโ js/
โ โโโ app.js
โโโ images/
โโโ logo.png
Access them directly:
http://localhost:8080/css/style.csshttp://localhost:8080/images/logo.png
Custom Location
Want files from a different folder?
@Configuration
public class WebConfig
implements WebMvcConfigurer {
@Override
public void addResourceHandlers(
ResourceHandlerRegistry registry) {
registry.addResourceHandler("/files/**")
.addResourceLocations("file:/data/files/");
}
}
Now /files/photo.jpg serves from /data/files/photo.jpg!
๐ CORS Configuration: The Guest Pass System
CORS (Cross-Origin Resource Sharing) is like a guest pass system. When your frontend lives at frontend.com but your API lives at api.com, the browser says โWait! Are you allowed to talk to each other?โ
The Problem
graph LR A["๐ฅ๏ธ frontend.com"] -->|Request| B["๐ Browser"] B -->|"Is api.com OK?"| C["๐ api.com"] C -->|"Yes, allow frontend.com"| B B -->|โ Pass Request| C
Solution 1: Per-Controller
@RestController
@CrossOrigin(origins = "http://frontend.com")
public class MyController {
@GetMapping("/data")
public String getData() {
return "Hello from API!";
}
}
Solution 2: Global Configuration
@Configuration
public class CorsConfig
implements WebMvcConfigurer {
@Override
public void addCorsMappings(
CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://frontend.com")
.allowedMethods("GET", "POST", "PUT")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
What Each Setting Means
| Setting | Purpose |
|---|---|
allowedOrigins |
Who can talk to us |
allowedMethods |
GET, POST, PUT, DELETE |
allowedHeaders |
Which headers are OK |
allowCredentials |
Allow cookies? |
maxAge |
Cache preflight (seconds) |
๐ฆ Filter vs Interceptor: Security Guards vs Concierge
This is where many developers get confused! Letโs clear it up with our hotel analogy:
Servlet Filter = Security Guard ๐ก๏ธ
The security guard stands at the building entrance. They check EVERYONE - guests, delivery people, even staff. They work at the Servlet level, before Spring even sees the request.
@Component
public class LoggingFilter
implements Filter {
@Override
public void doFilter(
ServletRequest req,
ServletResponse res,
FilterChain chain) throws Exception {
System.out.println("๐ฎ Guard: Someone arrived!");
// Let them through
chain.doFilter(req, res);
System.out.println("๐ฎ Guard: Someone left!");
}
}
Interceptor = Concierge ๐ฉ
The concierge stands in the lobby, after security. They only deal with hotel guests (Spring MVC requests). They can see where guests are going and help them along the way.
@Component
public class LoggingInterceptor
implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest req,
HttpServletResponse res,
Object handler) {
System.out.println("๐ฉ Concierge: Guest heading to "
+ req.getRequestURI());
return true; // Let them proceed
}
@Override
public void postHandle(...) {
System.out.println("๐ฉ Concierge: Guest finished!");
}
}
The Key Differences
graph TD A["๐จ HTTP Request"] --> B["๐ก๏ธ FILTER"] B --> C["๐ฑ Spring DispatcherServlet"] C --> D["๐ฉ INTERCEPTOR"] D --> E["๐ฏ Controller"] E --> D D --> C C --> B B --> F["๐ค HTTP Response"]
| Feature | Filter | Interceptor |
|---|---|---|
| Level | Servlet (low) | Spring MVC (high) |
| Access to | Request/Response only | Handler, ModelAndView |
| Use for | Logging, Encoding, Security | Auth, Logging, Timing |
| Configured in | FilterRegistrationBean | WebMvcConfigurer |
๐ง Servlet Filters: Deep Dive
Filters are the workhorses of request processing. They wrap around your entire application like layers of an onion.
Common Use Cases
- Logging - Track all requests
- Encoding - Set character encoding
- Security - Check tokens/headers
- Compression - Gzip responses
Creating a Filter
@Component
@Order(1) // Lower = runs first
public class AuthFilter implements Filter {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws Exception {
HttpServletRequest req =
(HttpServletRequest) request;
String token = req.getHeader("Auth-Token");
if (token == null) {
HttpServletResponse res =
(HttpServletResponse) response;
res.setStatus(401);
res.getWriter().write("No token!");
return; // STOP here!
}
// Token exists, continue
chain.doFilter(request, response);
}
}
Registering with URL Patterns
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<AuthFilter>
authFilterRegistration() {
FilterRegistrationBean<AuthFilter> bean =
new FilterRegistrationBean<>();
bean.setFilter(new AuthFilter());
bean.addUrlPatterns("/api/*");
bean.setOrder(1);
return bean;
}
}
Filter Chain Flow
graph TD A["๐จ Request"] --> B["Filter 1: Logging"] B --> C["Filter 2: Encoding"] C --> D["Filter 3: Auth"] D --> E["๐ฏ Your Controller"] E --> D D --> C C --> B B --> F["๐ค Response"]
Each filter can:
- Modify the request before passing it on
- Stop the chain (like auth failure)
- Modify the response on the way back
๐ฏ Putting It All Together
Hereโs how all these pieces work in a real Spring Boot app:
graph TD A["๐ Browser Request"] --> B["๐ก๏ธ Servlet Filters"] B --> C{๐ Static Resource?} C -->|Yes| D["๐ผ๏ธ Serve File"] C -->|No| E["๐ฑ DispatcherServlet"] E --> F{๐ CORS OK?} F -->|No| G["โ CORS Error"] F -->|Yes| H["๐ฉ Interceptors"] H --> I["๐ฏ Controller"] I --> J{๐ฆ File Upload?} J -->|Yes| K["๐ค MultipartFile"] J -->|No| L["๐ Regular Handler"]
๐ Quick Summary
| Feature | What It Does | One-Line Example |
|---|---|---|
| File Upload | Handle uploaded files | @RequestParam MultipartFile file |
| Static Resources | Serve CSS/JS/images | Put in /static/ folder |
| CORS | Allow cross-origin requests | @CrossOrigin(origins="...") |
| Filter | Low-level request processing | implements Filter |
| Interceptor | Spring-level request processing | implements HandlerInterceptor |
๐ก Remember This!
Filters are like security guards - they see everything and work at the door.
Interceptors are like concierges - they work inside Spring and know about your controllers.
CORS is like a guest pass - it says whoโs allowed to talk to your API.
Static resources are like hotel decorations - always there, never changing.
File uploads are like luggage handling - catch, validate, store!
Youโve now mastered the Web Layer! ๐ Your Spring Boot hotel is ready to welcome guests (requests) with proper security, beautiful decorations, and excellent service!
