๐ Advanced Servlet Features: The Restaurant Kitchen Story
Imagine you run a busy restaurant kitchen. Regular cooking works fine when there are few orders. But what happens during rush hour? What if someone orders a huge cake that takes an hour? What if customers want to bring their own ingredients? And how do you keep the kitchen safe from intruders?
Thatโs exactly what Advanced Servlet Features solve for web applications!
๐ญ The Three Superpowers
| Feature | Kitchen Analogy | What It Does |
|---|---|---|
| Async Processing | Chef handles slow orders without blocking | Long tasks donโt freeze your app |
| File Upload | Accepting customer ingredients | Users can send files to server |
| Security | Kitchen access control | Only authorized people get in |
1๏ธโฃ Servlet Async Processing
๐ณ The Problem: The Slow Cake Order
Picture this: A customer orders a special cake that takes 1 hour to bake.
Without Async (Bad Kitchen):
๐จโ๐ณ Chef starts cake
โณ All other customers WAIT 1 hour
๐ Everyone is angry
With Async (Smart Kitchen):
๐จโ๐ณ Chef puts cake in oven
๐ Takes other orders immediately
๐ Oven timer rings when ready
๐ Cake gets delivered
๐ฏ What is Async Processing?
Async means โstart now, finish laterโ. The servlet says: โIโll work on this, but donโt wait for me. Go help other customers!โ
๐ก How It Works
graph TD A["Request Arrives"] --> B["Start Async Context"] B --> C["Thread Returns to Pool"] C --> D["Background Work Happens"] D --> E["Async Thread Finishes"] E --> F["Response Sent"]
โจ The Magic Code
@WebServlet(urlPatterns = "/slow-task",
asyncSupported = true)
public class SlowServlet extends HttpServlet {
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) {
// ๐ฌ Start async mode
AsyncContext ctx = req.startAsync();
// โฐ Set timeout (30 seconds)
ctx.setTimeout(30000);
// ๐ Run in background
ctx.start(() -> {
try {
// Simulate slow work
Thread.sleep(5000);
// Write response
ctx.getResponse().getWriter()
.write("Done!");
// ๐ Signal completion
ctx.complete();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
๐งฉ Key Parts Explained
| Part | What It Does | Like In Kitchen |
|---|---|---|
asyncSupported = true |
Enables async mode | โWe take slow ordersโ sign |
startAsync() |
Begins async processing | Put cake in oven |
setTimeout() |
Max wait time | Oven timer |
ctx.start(...) |
Run background task | Baker works on cake |
ctx.complete() |
Signal โIโm done!โ | Ring the bell |
๐ง Async Listeners: The Kitchen Bell System
Want to know when things happen? Use listeners!
ctx.addListener(new AsyncListener() {
public void onComplete(AsyncEvent e) {
System.out.println("โ
Task done!");
}
public void onTimeout(AsyncEvent e) {
System.out.println("โฐ Taking too long!");
}
public void onError(AsyncEvent e) {
System.out.println("โ Something broke!");
}
public void onStartAsync(AsyncEvent e) {
System.out.println("๐ Starting!");
}
});
2๏ธโฃ File Upload in Servlets
๐ฆ The Problem: Customer Brings Ingredients
What if customers want to upload their own recipe photos? Or submit documents? Your servlet needs to accept files!
๐ฏ Two Ways to Accept Files
Think of it like two different delivery systems:
| Method | Annotation | Likeโฆ |
|---|---|---|
| @MultipartConfig | On servlet class | Permanent mailbox |
| web.xml config | In deployment file | Shared mailroom |
โจ The Magic Code
@WebServlet("/upload")
@MultipartConfig(
fileSizeThreshold = 1024 * 1024, // 1MB
maxFileSize = 5 * 1024 * 1024, // 5MB
maxRequestSize = 10 * 1024 * 1024 // 10MB
)
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
// ๐ฅ Get the uploaded file
Part filePart = req.getPart("myFile");
// ๐ Get original filename
String fileName = filePart
.getSubmittedFileName();
// ๐พ Save to disk
String path = "/uploads/" + fileName;
filePart.write(path);
resp.getWriter().write("Uploaded: " + fileName);
}
}
๐งฉ @MultipartConfig Options
| Option | What It Means | Real Example |
|---|---|---|
fileSizeThreshold |
Memory limit before saving to disk | 1MB |
maxFileSize |
Max size per file | 5MB |
maxRequestSize |
Max total upload size | 10MB |
location |
Temp folder path | โ/tmpโ |
๐ Working with Parts
// Get one file by name
Part photo = req.getPart("photo");
// Get ALL uploaded files
Collection<Part> allParts = req.getParts();
// Loop through each file
for (Part part : allParts) {
String name = part.getSubmittedFileName();
long size = part.getSize();
String type = part.getContentType();
// Save it!
part.write("/uploads/" + name);
}
๐ Part Methods Cheatsheet
graph TD A["Part Object"] --> B["getSubmittedFileName"] A --> C["getSize"] A --> D["getContentType"] A --> E["getInputStream"] A --> F["write path"] B --> G["photo.jpg"] C --> H["2048576 bytes"] D --> I["image/jpeg"]
3๏ธโฃ Servlet Security
๐ The Problem: Kitchen Intruders!
Not everyone should enter your kitchen:
- Customers can order food
- Staff can enter kitchen
- Manager can access the safe
Thatโs role-based security!
๐ฏ Three Security Methods
| Method | Where | Best For |
|---|---|---|
| Annotations | In code | Simple rules |
| web.xml | Config file | Flexible rules |
| Programmatic | Runtime code | Dynamic checks |
๐ท๏ธ Method 1: Annotation Security
@WebServlet("/admin")
@ServletSecurity(
@HttpConstraint(rolesAllowed = {"admin"})
)
public class AdminServlet extends HttpServlet {
// Only admins can access this!
}
Different rules for different actions:
@ServletSecurity(
value = @HttpConstraint(
rolesAllowed = {"user", "admin"}
),
httpMethodConstraints = {
@HttpMethodConstraint(
value = "DELETE",
rolesAllowed = {"admin"}
)
}
)
This means:
- ๐ฅ GET/POST: Users and admins allowed
- ๐๏ธ DELETE: Only admins allowed
๐ Method 2: web.xml Security
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Area</web-resource-name>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
๐ Authentication Methods
| Method | How It Works | Likeโฆ |
|---|---|---|
| BASIC | Browser popup | Doorbell |
| FORM | Custom login page | Reception desk |
| DIGEST | Encrypted password | Secret handshake |
| CLIENT-CERT | SSL certificate | VIP badge |
๐ฎ Method 3: Programmatic Security
Check permissions in your code:
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) {
// ๐ค Who is logged in?
String user = req.getRemoteUser();
// ๐ญ What role do they have?
if (req.isUserInRole("admin")) {
showAdminPanel();
} else if (req.isUserInRole("user")) {
showUserDashboard();
} else {
showLoginPage();
}
// ๐ Get security details
Principal principal = req.getUserPrincipal();
if (principal != null) {
String name = principal.getName();
}
}
๐ HTTPS Transport Security
Force secure connections:
In annotations:
@HttpConstraint(
rolesAllowed = {"user"},
transportGuarantee =
TransportGuarantee.CONFIDENTIAL
)
In web.xml:
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
| Guarantee | Meaning |
|---|---|
NONE |
HTTP is fine |
INTEGRAL |
Data canโt be changed |
CONFIDENTIAL |
Must use HTTPS |
๐ Putting It All Together
Imagine a secure file upload system:
@WebServlet("/secure-upload")
@MultipartConfig(maxFileSize = 5000000)
@ServletSecurity(
@HttpConstraint(
rolesAllowed = {"user", "admin"},
transportGuarantee =
TransportGuarantee.CONFIDENTIAL
)
)
public class SecureUploadServlet
extends HttpServlet {
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
// ๐ Who's uploading?
String user = req.getRemoteUser();
// ๐ฆ Get the file
Part file = req.getPart("document");
// ๐พ Save with user folder
String path = "/uploads/" + user + "/"
+ file.getSubmittedFileName();
file.write(path);
resp.getWriter().write("Secure upload done!");
}
}
๐ Key Takeaways
graph TD A["Advanced Servlet Features"] --> B["Async Processing"] A --> C["File Upload"] A --> D["Security"] B --> B1[Don't block threads] B --> B2["Handle slow tasks"] B --> B3["Use AsyncContext"] C --> C1["Use @MultipartConfig"] C --> C2["Get Parts from request"] C --> C3["Set size limits"] D --> D1["Role-based access"] D --> D2["Authentication methods"] D --> D3["HTTPS enforcement"]
๐ฏ Remember These Golden Rules
| Feature | Remember | Avoid |
|---|---|---|
| Async | Always call complete() |
Forgetting timeout |
| Upload | Set file size limits | No limits = danger |
| Security | Define all roles | Hardcoding passwords |
๐ You Did It!
You now understand the three superpowers of advanced servlets:
- Async Processing ๐ - Handle slow tasks without freezing
- File Upload ๐ - Accept files from users safely
- Security ๐ - Control who can access what
Just like a well-run restaurant kitchen, your web application can now:
- โ Handle rush hour traffic
- โ Accept customer โingredientsโ (files)
- โ Keep intruders out
Go build something awesome! ๐
