← Назад к вопросам

Как подбирается хэш для снижения количества коллизий в 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

  1. Используй Thymeleaf - modern, безопасный, удобный
  2. Разделяй логику - контроллер не должен генерировать HTML
  3. Используй layout/base template - для переиспользования дизайна
  4. Валидируй данные - @Valid на @ModelAttribute
  5. Используй static files - CSS/JS в /static
  6. Кэшируй шаблоны - spring.thymeleaf.cache=true в production
  7. Логируй ошибки - шаблоны могут содержать ошибки

Кратко: Используй Thymeleaf для современных приложений, передавай данные через Model, возвращай имя шаблона из контроллера. Spring найдёт и отрендирует HTML.