← Назад к вопросам
Как подбирается хэш для снижения количества коллизий в Hashtable
2.0 Middle🔥 101 комментариев
#Коллекции#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Как создать сервис, возвращающий представление в виде HTML-страницы
В Spring есть несколько способов возвращать HTML представления: Thymeleaf, JSP, FreeMarker, Groovy Template, или обычный HTML.
1. Thymeleaf (рекомендуется) - современный способ
Зависимость в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Контроллер:
@Controller
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public String listUsers(Model model) {
List<User> users = userService.findAll();
// Добавляем данные в model
model.addAttribute("users", users);
model.addAttribute("title", "User List");
// Возвращаем имя шаблона (без расширения)
// Spring найдёт /templates/users/list.html
return "users/list";
}
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
User user = userService.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
model.addAttribute("user", user);
return "users/detail";
}
}
Шаблон (src/main/resources/templates/users/list.html):
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${title}">Users</title>
</head>
<body>
<h1 th:text="${title}">User List</h1>
<table>
<tr>
<th>ID</th>
<th>Email</th>
<th>Name</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.id}">1</td>
<td th:text="${user.email}">user@example.com</td>
<td th:text="${user.name}">John Doe</td>
</tr>
</table>
</body>
</html>
2. JSP (старый способ)
Конфигурация:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Контроллер:
@Controller
public class JspController {
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("name", "World");
return "hello"; // Ищет /WEB-INF/jsp/hello.jsp
}
}
application.properties:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
JSP (src/main/webapp/WEB-INF/jsp/hello.jsp):
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Hello Page</title>
</head>
<body>
<h1>Hello <%= request.getAttribute("name") %></h1>
</body>
</html>
3. FreeMarker
Зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
Контроллер - то же самое:
@Controller
public class ProductController {
@GetMapping("/products")
public String listProducts(Model model) {
List<Product> products = productService.findAll();
model.addAttribute("products", products);
return "products/list"; // Ищет /templates/products/list.ftl
}
}
Шаблон (src/main/resources/templates/products/list.ftl):
<!DOCTYPE html>
<html>
<body>
<h1>Products</h1>
<ul>
<#list products as product>
<li>${product.name} - ${product.price}</li>
</#list>
</ul>
</body>
</html>
4. Возврат обычного HTML
GET -> HTML:
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
// Возвращаем шаблон из /templates/home.html
return "home";
}
@GetMapping("/static-page")
public String staticPage() {
// Возвращаем статический HTML из /static/page.html
return "redirect:/page.html";
}
}
5. REST контроллер с HTML строкой
@RestController
public class HtmlRestController {
@GetMapping("/html", produces = "text/html;charset=UTF-8")
public String getHtml() {
return "<html>" +
"<body>" +
"<h1>Привет мир!</h1>" +
"</body>" +
"</html>";
}
}
6. Передача данных из контроллера в шаблон
@Controller
public class DataController {
@GetMapping("/data")
public String showData(Model model) {
// Простые типы
model.addAttribute("name", "John");
model.addAttribute("age", 30);
// Объект
User user = new User(1L, "john@example.com");
model.addAttribute("user", user);
// Коллекция
List<String> roles = Arrays.asList("USER", "ADMIN");
model.addAttribute("roles", roles);
return "data-page";
}
}
Thymeleaf шаблон:
<h1 th:text="'Hello, ' + ${name}">Hello</h1>
<p th:text="${age}">Age</p>
<p th:text="${user.email}">Email</p>
<ul>
<li th:each="role : ${roles}" th:text="${role}">Role</li>
</ul>
7. Обработка форм
Контроллер:
@Controller
public class FormController {
@GetMapping("/form")
public String showForm(Model model) {
model.addAttribute("user", new User());
return "form";
}
@PostMapping("/form")
public String submitForm(@ModelAttribute User user) {
// user содержит данные из формы
userService.save(user);
return "redirect:/users"; // Редирект после сохранения
}
}
Шаблон:
<form th:action="@{/form}" th:object="${user}" method="post">
<input type="hidden" th:field="*{id}" />
<label>Email:</label>
<input type="email" th:field="*{email}" required />
<label>Name:</label>
<input type="text" th:field="*{name}" required />
<button type="submit">Save</button>
</form>
8. Структура проекта
src/main/resources/
├── templates/ # Для Thymeleaf/FreeMarker
│ ├── users/
│ │ ├── list.html
│ │ └── detail.html
│ ├── products/
│ │ └── list.html
│ ├── layout/
│ │ └── base.html # Базовый шаблон
│ └── home.html
├── static/ # Для статических файлов
│ ├── css/
│ ├── js/
│ └── images/
└── application.properties
9. Сравнение шаблонизаторов
| Шаблонизатор | Простота | Производительность | Рекомендация |
|---|---|---|---|
| Thymeleaf | Средняя | Хорошая | Для современных проектов |
| JSP | Низкая | Хорошая | Для legacy проектов |
| FreeMarker | Средняя | Отличная | Для большой нагрузки |
| Groovy | Низкая | Хорошая | Редко используется |
10. Best Practices
- Используй Thymeleaf - modern, безопасный, удобный
- Разделяй логику - контроллер не должен генерировать HTML
- Используй layout/base template - для переиспользования дизайна
- Валидируй данные - @Valid на @ModelAttribute
- Используй static files - CSS/JS в /static
- Кэшируй шаблоны - spring.thymeleaf.cache=true в production
- Логируй ошибки - шаблоны могут содержать ошибки
Кратко: Используй Thymeleaf для современных приложений, передавай данные через Model, возвращай имя шаблона из контроллера. Spring найдёт и отрендирует HTML.