Response
No need to write a file — I'll just print the source directly.
```java
package com.acme.billing;
import com.acme.common.ApiResponse;
import com.acme.common.PageMeta;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/billing")
public class InvoiceController {
private static final int MAX_PAGE_SIZE = 100;
private final InvoiceService invoiceService;
public InvoiceController(InvoiceService invoiceService) {
this.invoiceService = invoiceService;
}
@GetMapping("/invoices")
public ApiResponse<?> listInvoices(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int size) {
int pageNo = Math.max(page, 1);
int pageSize = Math.clamp(size, 1, MAX_PAGE_SIZE);
InvoiceQueryResult result = invoiceService.listInvoices(pageNo, pageSize);
return ApiResponse.ok(result.items(), PageMeta.of(pageNo, pageSize, result.total()));
}
}
```
Convention notes:
- Constructor injection (no `@Autowired`/Lombok), 1-based `page`/`size` clamped to `MAX_PAGE_SIZE = 100`, and the response wrapped via `ApiResponse.ok(items, PageMeta.of(...))` rather than returning the raw list — I assumed `ApiResponse`/`PageMeta` already exist in a shared `com.acme.common` package per house convention.
- Kept the controller thin (one service call, no try/catch) — error mapping is left to the existing `@RestControllerAdvice`, and pagination/validation logic beyond clamping stays in `InvoiceService`.