or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

api-versioning.mdasync.mdconfiguration.mdcontent-negotiation.mdcontroller-annotations.mdcore-framework.mdcors.mddata-binding.mdexception-handling.mdflash-attributes.mdfunctional-endpoints.mdi18n.mdindex.mdinterceptors.mdmultipart.mdrequest-binding.mdresource-handling.mdresponse-handling.mduri-building.mdview-resolution.md
tile.json

uri-building.mddocs/

URI Building

Utilities for building URIs from controller mappings and request information with proper encoding, context path handling, and type-safe URI construction from controller methods.

Capabilities

ServletUriComponentsBuilder

Servlet-specific extension of UriComponentsBuilder with additional factory methods to extract information from servlet requests.

/**
 * UriComponentsBuilder with additional static factory methods to create links
 * based on the current HttpServletRequest.
 */
public class ServletUriComponentsBuilder extends UriComponentsBuilder {
    /**
     * Create a new ServletUriComponentsBuilder from the HttpServletRequest.
     *
     * @param request the source request
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromRequest(HttpServletRequest request) {}

    /**
     * Create a new ServletUriComponentsBuilder with a scheme, host, and port extracted
     * from the HttpServletRequest but leaving the context path and further untouched.
     *
     * @param request the source request
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromContextPath(HttpServletRequest request) {}

    /**
     * Same as fromContextPath but also appending the servlet mapping.
     *
     * @param request the source request
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromServletMapping(HttpServletRequest request) {}

    /**
     * Create a new ServletUriComponentsBuilder from the HttpServletRequest with
     * the full request URI including the scheme, host, port, context path, servlet
     * mapping, and the part of the URL following the servlet mapping.
     *
     * @param request the source request
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromRequestUri(HttpServletRequest request) {}

    /**
     * Variant of fromContextPath using the current request.
     *
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromCurrentContextPath() {}

    /**
     * Variant of fromServletMapping using the current request.
     *
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromCurrentServletMapping() {}

    /**
     * Variant of fromRequestUri using the current request.
     *
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromCurrentRequestUri() {}

    /**
     * Variant of fromRequest using the current request.
     *
     * @return the builder
     */
    public static ServletUriComponentsBuilder fromCurrentRequest() {}
}

Usage Example:

@RestController
@RequestMapping("/api/users")
public class UserController {

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User created = userService.save(user);

        // Build URI for the created resource
        URI location = ServletUriComponentsBuilder
            .fromCurrentRequest()
            .path("/{id}")
            .buildAndExpand(created.getId())
            .toUri();

        return ResponseEntity.created(location).body(created);
    }

    @GetMapping("/{id}/profile")
    public ResponseEntity<Profile> getUserProfile(@PathVariable Long id) {
        Profile profile = userService.getProfile(id);

        // Build URI for related resource
        URI avatarUri = ServletUriComponentsBuilder
            .fromCurrentContextPath()
            .path("/api/users/{id}/avatar")
            .buildAndExpand(id)
            .toUri();

        profile.setAvatarUrl(avatarUri.toString());
        return ResponseEntity.ok(profile);
    }

    @GetMapping
    public ResponseEntity<List<User>> getUsers(@RequestParam(defaultValue = "0") int page) {
        List<User> users = userService.findAll(page);

        // Build pagination links
        HttpHeaders headers = new HttpHeaders();

        if (page > 0) {
            URI prevUri = ServletUriComponentsBuilder
                .fromCurrentRequest()
                .replaceQueryParam("page", page - 1)
                .build()
                .toUri();
            headers.add("Link", "<" + prevUri + ">; rel=\"prev\"");
        }

        URI nextUri = ServletUriComponentsBuilder
            .fromCurrentRequest()
            .replaceQueryParam("page", page + 1)
            .build()
            .toUri();
        headers.add("Link", "<" + nextUri + ">; rel=\"next\"");

        return ResponseEntity.ok().headers(headers).body(users);
    }
}

MvcUriComponentsBuilder

Builder for URIs to Spring MVC controller methods with type-safe method references.

/**
 * Creates URIs to Spring MVC controller methods. Supports extracting URI template variable
 * values, expanding template variables, and encoding the result, with support for both
 * string-based method lookup and type-safe method invocation.
 */
public class MvcUriComponentsBuilder {
    /**
     * Create a UriComponentsBuilder from the mapping of a controller class
     * and current request information.
     *
     * @param controllerType the controller class
     * @return the builder
     */
    public static UriComponentsBuilder fromController(Class<?> controllerType) {}

    /**
     * Create a UriComponentsBuilder by invoking a "mock" controller method.
     *
     * @param invocationInfo either the value returned from a "mock" controller
     * invocation or the "mock" controller itself after an invocation
     * @return the builder
     */
    public static UriComponentsBuilder fromMethodCall(Object invocationInfo) {}

    /**
     * Create a UriComponentsBuilder from the name of a method and a controller class.
     *
     * @param controllerType the controller class
     * @param methodName the method name
     * @param args method argument values
     * @return the builder
     */
    public static UriComponentsBuilder fromMethodName(Class<?> controllerType,
                                                     String methodName,
                                                     Object... args) {}

    /**
     * Create a UriComponentsBuilder from a controller method and an argument values array
     * to be used to prepare the URI. This method supports controllers annotated with
     * @RequestMapping where the mapping has a name.
     *
     * @param method the controller method
     * @param args argument values matching the method parameters
     * @return the builder
     */
    public static UriComponentsBuilder fromMethod(Method method, Object... args) {}

    /**
     * Create a UriComponentsBuilder by looking up the mapping by name.
     *
     * @param mappingName the mapping name
     * @return the builder
     */
    public static UriComponentsBuilder fromMappingName(String mappingName) {}

    /**
     * Return a "mock" controller instance of the given type that can be used to
     * record method invocations which can then be used to build a URI via fromMethodCall.
     *
     * @param controllerType the target controller type
     * @param <T> the type
     * @return the mock controller instance
     */
    public static <T> T on(Class<T> controllerType) {}
}

Usage Example:

@RestController
@RequestMapping("/api/products")
public class ProductController {

    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return productService.findById(id);
    }

    @GetMapping
    public List<Product> searchProducts(@RequestParam String query) {
        return productService.search(query);
    }
}

@Service
public class ProductLinkService {

    public URI getProductUri(Long productId) {
        // Type-safe URI building
        return MvcUriComponentsBuilder
            .fromMethodCall(MvcUriComponentsBuilder
                .on(ProductController.class)
                .getProduct(productId))
            .build()
            .toUri();
    }

    public URI getSearchUri(String query) {
        // Using method name
        return MvcUriComponentsBuilder
            .fromMethodName(ProductController.class, "searchProducts", query)
            .build()
            .toUri();
    }

    public URI getProductListUri() {
        // From controller
        return MvcUriComponentsBuilder
            .fromController(ProductController.class)
            .build()
            .toUri();
    }
}

// In views (JSP/Thymeleaf)
@Controller
public class ViewController {

    @GetMapping("/products-page")
    public String showProductsPage(Model model) {
        // Build URIs for use in views
        String productUri = MvcUriComponentsBuilder
            .fromMethodCall(MvcUriComponentsBuilder
                .on(ProductController.class)
                .getProduct(123L))
            .build()
            .encode()
            .toUriString();

        model.addAttribute("productUri", productUri);
        return "products";
    }
}

// Using mapping names
@RestController
@RequestMapping("/api/orders")
public class OrderController {

    @GetMapping(value = "/{id}", name = "getOrder")
    public Order getOrder(@PathVariable Long id) {
        return orderService.findById(id);
    }

    @PostMapping
    public ResponseEntity<Order> createOrder(@RequestBody Order order) {
        Order created = orderService.save(order);

        // Build URI using mapping name
        URI location = MvcUriComponentsBuilder
            .fromMappingName("getOrder")
            .arg(0, created.getId())
            .build();

        return ResponseEntity.created(location).body(created);
    }
}

Types

UriComponents

Represents an immutable collection of URI components.

public interface UriComponents {
    String getScheme();
    String getSchemeSpecificPart();
    String getUserInfo();
    String getHost();
    int getPort();
    String getPath();
    List<String> getPathSegments();
    String getQuery();
    MultiValueMap<String, String> getQueryParams();
    String getFragment();
    String toUriString();
    URI toUri();
    UriComponents encode();
    UriComponents encode(Charset charset);
    UriComponents expand(Map<String, ?> uriVariables);
    UriComponents expand(Object... uriVariableValues);
    UriComponents normalize();
}

UriComponentsBuilder

Builder for UriComponents.

public class UriComponentsBuilder implements Cloneable {
    public static UriComponentsBuilder newInstance() {}
    public static UriComponentsBuilder fromUriString(String uri) {}
    public static UriComponentsBuilder fromUri(URI uri) {}
    public UriComponentsBuilder scheme(String scheme) {}
    public UriComponentsBuilder userInfo(String userInfo) {}
    public UriComponentsBuilder host(String host) {}
    public UriComponentsBuilder port(int port) {}
    public UriComponentsBuilder path(String path) {}
    public UriComponentsBuilder pathSegment(String... pathSegments) {}
    public UriComponentsBuilder queryParam(String name, Object... values) {}
    public UriComponentsBuilder queryParams(MultiValueMap<String, String> params) {}
    public UriComponentsBuilder replaceQueryParam(String name, Object... values) {}
    public UriComponentsBuilder replaceQueryParams(MultiValueMap<String, String> params) {}
    public UriComponentsBuilder fragment(String fragment) {}
    public UriComponents build() {}
    public UriComponents build(boolean encoded) {}
    public UriComponents buildAndExpand(Map<String, ?> uriVariables) {}
    public UriComponents buildAndExpand(Object... uriVariableValues) {}
}