#java #spring #spring-boot
Вопрос:
В рамках моего университетского проекта меня попросили реализовать простое приложение spring-boot(только для бэкэнда), которое может взаимодействовать с почтальоном через HTTP-запросы.
Проект построен в архитектуре контроллер-сервис-репозиторий и содержит только 1 объект(объект публикации со строковым содержимым) и 2 конечных точки(создать новое сообщение, получить все сообщения).
Я знаю, что есть несколько способов настройки компонентов в spring-boot:
- с помощью внешнего XML-файла.
- С аннотацией @конфигурации и аннотацией @Bean
- С аннотацией @компонента(@RestController,@Service, @JpaRepository)
3-й способ работает отлично, но меня попросили реализовать 2-й способ, и я действительно изо всех сил стараюсь, чтобы это сработало.
Я получаю:
Исключение ServletException: Путь кругового представления [сообщение]: снова отправит сообщение обратно на текущий URL-адрес обработчика [/сообщение]. Проверьте настройки вашего решателя представлений!
Попытался изучить это исключение, и мне удалось «решить» его, добавив эту зависимость maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.5.2</version>
</dependency>
что привело к:
"org.thymeleaf.exceptions.TemplateInputException: Error resolving template [post], template might not exist or might not be accessible by any of the configured Template Resolvers"
Что я делаю не так?
Класс конфигурации:
@Configuration
@EnableJpaRepositories(basePackages = {
"com.example.microblog.post.domain.repository"
})
public class ApplicationBeans {
@Bean
public PostController postController(PostService postService){
return new PostController(postService);
}
@Bean
public PostService postService(){
return new PostService();
}
}
Класс контроллера:
@AllArgsConstructor
@RequestMapping(path = "post")
public class PostController {
@Autowired
private PostService service;
@CrossOrigin(origins = "http://localhost:4200")
@PostMapping("")
public PostEntity create(@RequestBody PostDto dto) {
return service.create(dto);
}
@GetMapping("/all")
@CrossOrigin(origins = "http://localhost:4200")
public List<PostEntity> getAll() {
return service.getAll();
}
}
Класс обслуживания:
@Transactional
public class PostService {
@Autowired
private PostRepository PostRepository;
public PostEntity create(PostDto dto){
PostEntity newPost = new PostEntity(dto.getContent());
return PostRepository.save(newPost);
}
public List<PostEntity> getAll(){
return PostRepository.findAll();
}
Класс репозитория:
public interface PostRepository extends JpaRepository<PostEntity,Long> {}
Комментарии:
1. Вместо изображений вашего кода, пожалуйста, опубликуйте свой реальный код. Проще получить полную картину, и это занимает меньше времени для людей, которые пытаются помочь.
2. Обратите внимание, что есть еще один вариант , который я использую для большинства своих компонентов: вы можете использовать
@Import(MyService.class)
на@Configuration
(включая ваши@SpringBootApplication
, для небольших программ).
Ответ №1:
Для второго подхода, при создании компонента, постарайтесь не использовать @Component/@Controller … в классе, для которого вы создаете компонент
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
Вы можете продолжать автоматически подключать их, как в третьем подходе, старайтесь не сохранять бобы с тем же именем
Комментарии:
1. «когда вы создаете компонент, старайтесь не использовать @Component/@Controller» — это именно то, что меня попросили сделать, и чего я пытаюсь достичь, но, как вы можете видеть, наш код очень похож, и он не работает. как мне решить это исключение TemplateInputException ?
Ответ №2:
Ваша ошибка указывает на то, что у вашего контроллера возникли трудности с решением ответа вашей Службы на допустимый ответ JSON.
Обратите внимание, что @RestController-это просто удобный способ добавить аннотацию @Controller и @Response. Когда вы просто добавляете аннотацию @Bean, вы не добавляете ни @Controller, ни @Response. Если вы хотите использовать класс контроллера без использования этих примечаний, вам необходимо реализовать функции, предоставляемые этими классами.
Однако я действительно не вижу способа, почему вариант 2 будет использоваться для класса контроллера. Если вы хотите использовать его для класса @Service (который выполняет то же самое, что и @Component), вы можете использовать подход, предложенный Рави.