### Example Jakarta MVC Controller Triggering Events in Java Source: https://context7.com/jakartaee/mvc/llms.txt This Java code provides an example of a Jakarta MVC controller (`MonitoredController`) designed to trigger various MVC lifecycle events. It includes methods for processing requests and initiating redirects, demonstrating how to interact with the MVC framework and its event system. The controller uses `@Inject` for `Models` and standard JAX-RS annotations. ```java // Example controller that triggers events: @Path("/monitored") @Controller public class MonitoredController { @Inject private Models models; @GET @Path("/process") public String process() throws InterruptedException { // BeforeControllerEvent fired before this Thread.sleep(100); // Simulate processing models.put("data", "processed"); models.put("timestamp", System.currentTimeMillis()); // AfterControllerEvent fired after this // BeforeProcessViewEvent fired before view rendering // AfterProcessViewEvent fired after view rendering return "result.jsp"; } @GET @Path("/redirect") public jakarta.ws.rs.core.Response redirect() { // ControllerRedirectEvent will be fired return jakarta.ws.rs.core.Response .seeOther(java.net.URI.create("/monitored/process")) .build(); } } ``` -------------------------------- ### Untitled No description -------------------------------- ### Untitled No description -------------------------------- ### Untitled No description -------------------------------- ### Using MvcContext for Application Context and URI Building in Java Source: https://context7.com/jakartaee/mvc/llms.txt Explains how to use the `MvcContext` interface in a Jakarta MVC controller to access application base paths, locales, configuration properties, CSRF tokens, and encoders for security. It also details how to build URIs to other controller methods using string references or the `UriBuilder`. ```java import jakarta.mvc.Controller; import jakarta.mvc.MvcContext; import jakarta.mvc.Models; import jakarta.mvc.UriRef; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.inject.Inject; import java.net.URI; import java.util.Map; import java.util.HashMap; @Path("/app") @Controller public class AppController { @Inject private MvcContext mvc; @Inject private Models models; @GET @Path("/info") public String showInfo() { // Get base path (context + application path) String basePath = mvc.getBasePath(); // e.g., "/myapp/api" // Get current locale String locale = mvc.getLocale().toString(); // e.g., "en_US" // Get configuration Object configValue = mvc.getConfig().getProperty("custom.property"); // Access CSRF token String csrfName = mvc.getCsrf().getName(); String csrfToken = mvc.getCsrf().getToken(); // Access encoders for XSS prevention String safeHtml = mvc.getEncoders().html(""); String safeJs = mvc.getEncoders().js("user's input"); models.put("basePath", basePath); models.put("locale", locale); models.put("csrfName", csrfName); models.put("csrfToken", csrfToken); models.put("safeHtml", safeHtml); return "info.jsp"; } @GET @Path("/navigation") public String showNavigation() { // Build URIs to other controller methods URI userProfileUri = mvc.uri("UserController#viewProfile"); Map params = new HashMap<>(); params.put("id", 123); URI productDetailsUri = mvc.uri("ProductController#getProductDetails", params); // Use UriBuilder for complex URIs URI customUri = mvc.uriBuilder("ProductController#listProducts") .queryParam("category", "electronics") .queryParam("sort", "price") .build(); models.put("userProfileUri", userProfileUri); models.put("productDetailsUri", productDetailsUri); models.put("customUri", customUri); return "navigation.jsp"; } @GET @Path("/product/{id}") @UriRef("product-details") public String productDetails(@PathParam("id") Long id) { models.put("productId", id); return "product.jsp"; } } ``` -------------------------------- ### Untitled No description -------------------------------- ### Implement Custom View Engine with Markdown Support in Java Source: https://context7.com/jakartaee/mvc/llms.txt This Java code implements the `ViewEngine` interface to create a custom view engine that supports Markdown files. It handles template processing, basic markdown to HTML conversion, and integrates with Jakarta MVC controllers. ```java import jakarta.mvc.engine.ViewEngine; import jakarta.mvc.engine.ViewEngineContext; import jakarta.mvc.engine.ViewEngineException; import jakarta.annotation.Priority; import jakarta.enterprise.context.ApplicationScoped; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Map; @ApplicationScoped @Priority(ViewEngine.PRIORITY_APPLICATION) public class CustomMarkdownViewEngine implements ViewEngine { @Override public boolean supports(String view) { // Support .md and .markdown files return view.endsWith(".md") || view.endsWith(".markdown"); } @Override public void processView(ViewEngineContext context) throws ViewEngineException { try { // Get view name and models String view = context.getView(); Map models = context.getModels(); // Read template from view folder String viewFolder = getViewFolder(context); String templatePath = viewFolder + view; String template = readTemplate(templatePath); // Simple template processing (replace ${variable} with model values) String processed = processTemplate(template, models); // Convert markdown to HTML (simplified) String html = convertMarkdownToHtml(processed); // Write to response try (Writer writer = new OutputStreamWriter( context.getOutputStream(), context.getCharset())) { writer.write(html); } } catch (IOException e) { throw new ViewEngineException("Error processing view: " + context.getView(), e); } } private String getViewFolder(ViewEngineContext context) { Object viewFolder = context.getConfiguration() .getProperty(ViewEngine.VIEW_FOLDER); return viewFolder != null ? viewFolder.toString() : ViewEngine.DEFAULT_VIEW_FOLDER; } private String readTemplate(String path) throws IOException { // Read template file from classpath or filesystem return "# ${title}\n\nWelcome ${username}!\n\n${content}"; } private String processTemplate(String template, Map models) { String result = template; for (Map.Entry entry : models.entrySet()) { String placeholder = "$" + "{" + entry.getKey() + "}"; String value = entry.getValue() != null ? entry.getValue().toString() : ""; result = result.replace(placeholder, value); } return result; } private String convertMarkdownToHtml(String markdown) { // Simplified markdown to HTML conversion String html = markdown; html = html.replaceAll("^# (.+)$\n", "

$1

\n"); html = html.replaceAll("^## (.+)$\n", "

$1

\n"); html = html.replaceAll("\n\n", "

"); return "" + html + ""; } } ``` ```java // Usage in controller: @Path("/docs") @Controller public class DocumentController { @Inject private Models models; @GET @Path("/readme") public String showReadme() { models.put("title", "Getting Started"); models.put("username", "Developer"); models.put("content", "This is the documentation."); return "readme.md"; // Will be processed by CustomMarkdownViewEngine } } ``` -------------------------------- ### Untitled No description -------------------------------- ### Define MVC Controllers with @Controller Annotation in Java Source: https://context7.com/jakartaee/mvc/llms.txt Marks JAX-RS resource methods or classes as MVC controllers. Enables returning view paths and accessing MVC features. This snippet demonstrates listing products and showing product details, injecting Models for data transfer. ```java import jakarta.mvc.Controller; import jakarta.mvc.Models; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; import jakarta.inject.Inject; @Path("/products") public class ProductController { @Inject private Models models; @GET @Path("/list") @Controller public String listProducts() { return "products/list.jsp"; } @GET @Path("/details") @Controller public String getProductDetails(@QueryParam("id") Long id) { // Add data to model models.put("productId", id); models.put("product", findProductById(id)); return "products/details.jsp"; } private Product findProductById(Long id) { // Database lookup logic return new Product(id, "Sample Product", 29.99); } static class Product { private Long id; private String name; private double price; public Product(Long id, String name, double price) { this.id = id; this.name = name; this.price = price; } // Getters omitted for brevity } } ``` -------------------------------- ### Using Models Interface to Pass Data from Controller to View in Java Source: https://context7.com/jakartaee/mvc/llms.txt Demonstrates how to use the `Models` interface in a Jakarta MVC controller to add data (simple values, complex objects, typed data) for consumption by view engines. It also shows how to retrieve data in a type-safe and non-typed manner, and access all data as a map. ```java import jakarta.mvc.Controller; import jakarta.mvc.Models; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.inject.Inject; import java.util.List; import java.util.ArrayList; @Path("/dashboard") @Controller public class DashboardController { @Inject private Models models; @GET public String showDashboard() { // Add simple values models.put("title", "Dashboard") .put("userName", "John Doe") .put("loginCount", 42); // Add complex objects List notifications = new ArrayList<>(); notifications.add("New message from admin"); notifications.add("System update available"); models.put("notifications", notifications); // Add typed data DashboardStats stats = new DashboardStats(150, 23, 5); models.put("stats", stats); return "dashboard.jsp"; } @GET @Path("/retrieve") public String retrieveExample() { // Simulate previous request where data was added models.put("count", 100); models.put("stats", new DashboardStats(200, 50, 10)); // Retrieve data - non-typed Object count = models.get("count"); // Retrieve data - type-safe DashboardStats stats = models.get("stats", DashboardStats.class); // Access as map java.util.Map allData = models.asMap(); models.put("retrieved", "Count: " + count + ", Stats: " + stats.totalUsers); return "retrieve.jsp"; } static class DashboardStats { int totalUsers; int activeUsers; int newUsers; public DashboardStats(int totalUsers, int activeUsers, int newUsers) { this.totalUsers = totalUsers; this.activeUsers = activeUsers; this.newUsers = newUsers; } } } ``` -------------------------------- ### Specify Default Views with @View Annotation in Java Source: https://context7.com/jakartaee/mvc/llms.txt Defines a default view path for controller methods that return void or null. This snippet shows user registration success and viewing user profiles, utilizing the @View annotation for automatic view resolution. ```java import jakarta.mvc.Controller; import jakarta.mvc.View; import jakarta.mvc.Models; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.FormParam; import jakarta.inject.Inject; @Path("/user") @Controller public class UserController { @Inject private Models models; @POST @Path("/register") @View("user/registration-success.jsp") public void registerUser( @FormParam("username") String username, @FormParam("email") String email) { // Process registration User newUser = createUser(username, email); models.put("user", newUser); // View is automatically resolved from @View annotation // No return statement needed for void methods } @GET @Path("/profile") @View("user/profile.jsp") @Controller public String viewProfile(@QueryParam("id") Long userId) { models.put("user", getUserById(userId)); // Return null to use default view from @View annotation return null; } private User createUser(String username, String email) { return new User(1L, username, email); } private User getUserById(Long id) { return new User(id, "john_doe", "john@example.com"); } static class User { private Long id; private String username; private String email; public User(Long id, String username, String email) { this.id = id; this.username = username; this.email = email; } } } ``` -------------------------------- ### Observing MVC Lifecycle Events in Java Source: https://context7.com/jakartaee/mvc/llms.txt This Java code demonstrates how to observe various Jakarta MVC lifecycle events such as BeforeControllerEvent, AfterControllerEvent, BeforeProcessViewEvent, AfterProcessViewEvent, and ControllerRedirectEvent. It logs details about controller execution, view processing, and redirects, and calculates request duration. This is useful for implementing cross-cutting concerns. ```java import jakarta.mvc.event.BeforeControllerEvent; import jakarta.mvc.event.AfterControllerEvent; import jakarta.mvc.event.BeforeProcessViewEvent; import jakarta.mvc.event.AfterProcessViewEvent; import jakarta.mvc.event.ControllerRedirectEvent; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.ws.rs.core.UriInfo; import java.time.Duration; import java.time.Instant; @ApplicationScoped public class MvcEventListener { private ThreadLocal requestStartTime = new ThreadLocal<>(); // Called before controller method execution public void beforeController(@Observes BeforeControllerEvent event) { requestStartTime.set(Instant.now()); UriInfo uriInfo = event.getUriInfo(); String path = uriInfo.getPath(); String method = uriInfo.getRequestUri().toString(); System.out.println("Before Controller: " + path); System.out.println("Resource class: " + event.getResourceInfo().getResourceClass()); System.out.println("Resource method: " + event.getResourceInfo().getResourceMethod()); } // Called after controller method execution public void afterController(@Observes AfterControllerEvent event) { Instant start = requestStartTime.get(); if (start != null) { Duration duration = Duration.between(start, Instant.now()); System.out.println("Controller execution time: " + duration.toMillis() + "ms"); } System.out.println("After Controller: " + event.getUriInfo().getPath()); } // Called before view processing public void beforeProcessView(@Observes BeforeProcessViewEvent event) { String view = event.getView(); System.out.println("Processing view: " + view); System.out.println("View engine: " + event.getEngine().getClass().getName()); // Access models being passed to view System.out.println("Model keys: " + String.join(", ", event.getModels().keySet())); } // Called after view processing public void afterProcessView(@Observes AfterProcessViewEvent event) { Instant start = requestStartTime.get(); if (start != null) { Duration totalDuration = Duration.between(start, Instant.now()); System.out.println("Total request time: " + totalDuration.toMillis() + "ms"); requestStartTime.remove(); } System.out.println("View rendered: " + event.getView()); } // Called when controller redirects public void onRedirect(@Observes ControllerRedirectEvent event) { String location = event.getLocation().toString(); System.out.println("Redirecting to: " + location); } } ``` -------------------------------- ### Untitled No description -------------------------------- ### Untitled No description -------------------------------- ### Java Jakarta EE MVC Controller: Using Resolved Locale Source: https://context7.com/jakartaee/mvc/llms.txt Demonstrates how to inject and use the resolved locale within a Jakarta EE MVC controller. The `MvcContext.getLocale()` method retrieves the locale determined by the active LocaleResolver chain. This locale is then used to select an appropriate greeting message. ```java import jakarta.mvc.Controller; import jakarta.mvc.MvcContext; import jakarta.inject.Inject; import jakarta.mvc.Models; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import java.util.Locale; @Path("/localized") @Controller public class LocalizedController { @Inject private MvcContext mvc; @Inject private Models models; @GET @Path("/greeting") public String showGreeting() { // Get resolved locale Locale locale = mvc.getLocale(); String greeting = switch (locale.getLanguage()) { case "de" -> "Hallo"; case "fr" -> "Bonjour"; case "es" -> "Hola"; default -> "Hello"; }; models.put("greeting", greeting); models.put("locale", locale.toString()); return "greeting.jsp"; } } ``` -------------------------------- ### Configure CSRF Protection in Jakarta EE MVC Application Source: https://context7.com/jakartaee/mvc/llms.txt Configure CSRF protection by setting properties in the `Application` class. Options include `OFF`, `EXPLICIT`, and `IMPLICIT`. You can also specify the CSRF header name. ```java import jakarta.mvc.security.Csrf; import jakarta.ws.rs.core.Application; import java.util.Map; import java.util.HashMap; public class MyApplication extends Application { @Override public Map getProperties() { Map props = new HashMap<>(); // Options: OFF, EXPLICIT, IMPLICIT (default) props.put(Csrf.CSRF_PROTECTION, Csrf.CsrfOptions.EXPLICIT); props.put(Csrf.CSRF_HEADER_NAME, "X-CSRF-TOKEN"); return props; } } ``` -------------------------------- ### Untitled No description -------------------------------- ### Untitled No description -------------------------------- ### Untitled No description -------------------------------- ### Prevent XSS with Encoders in Jakarta MVC (Java) Source: https://context7.com/jakartaee/mvc/llms.txt This Java code snippet illustrates how to leverage the `Encoders` interface from Jakarta MVC to sanitize user input for HTML and JavaScript contexts. It demonstrates encoding for direct HTML display, JavaScript string literals, and HTML attributes, preventing common XSS attack vectors. ```java import jakarta.mvc.Controller; import jakarta.mvc.Models; import jakarta.mvc.MvcContext; import jakarta.mvc.security.Encoders; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; import jakarta.inject.Inject; @Path("/content") @Controller public class ContentController { @Inject private MvcContext mvc; @Inject private Models models; @GET @Path("/display") public String displayUserContent( @QueryParam("comment") String userComment, @QueryParam("username") String username) { Encoders encoders = mvc.getEncoders(); // Encode HTML - prevents " // Output: "<script>alert('XSS')</script>" String safeUsername = encoders.html(username); // Input: "" // Output: "<img src=x onerror='alert(1)'>" // Encode JavaScript - safe for JS contexts String jsString = encoders.js(userComment); // Input: "'; alert('XSS'); var x='" // Output: "\x27; alert(\x27XSS\x27); var x\x3d\x27" models.put("safeComment", safeComment); models.put("safeUsername", safeUsername); models.put("jsString", jsString); models.put("rawComment", userComment); // For demonstration return "content.jsp"; } @GET @Path("/embed") public String embedUserData( @QueryParam("data") String userData, @QueryParam("url") String userUrl) { Encoders encoders = mvc.getEncoders(); // HTML encoding for element content and attributes String safeData = encoders.html(userData); String safeUrl = encoders.html(userUrl); // JavaScript encoding for inline scripts String jsData = encoders.js(userData); models.put("htmlSafeData", safeData); models.put("htmlSafeUrl", safeUrl); models.put("jsSafeData", jsData); return "embed.jsp"; } } // In JSP view (content.jsp): // //

${mvc.encoders.html(rawComment)}
// // // // // // ``` -------------------------------- ### Untitled No description === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.