1. Özet
Bu yazı boyunca bir spring boot uygulamasını Thymeleaf ve Jpa kullanarak gerçekleştireceğiz. Projemizi oluşturmak için Gradle kullanıcağız.
2. Uygulama Dosyaları
build.gradle
buildscript { ext { springBootVersion = '2.0.2.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.dogukanhan' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-data-jpa') compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-thymeleaf') compile('org.springframework.boot:spring-boot-starter-web') runtime('org.springframework.boot:spring-boot-devtools') runtime('mysql:mysql-connector-java') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.security:spring-security-test') }
settings.gradle
rootProject.name = 'spring101'
Dosyaları oluşturduktan sonra “gradle build” komutunu girelim
Proje yapısı ve src klasörünün içeriği şekildeki gibi olucaktır. Oluşturulmayan klasörleri ve dosyaları kendimiz oluşturalım veya yazının sonunda yer alan linkten indirebilirsiniz.
WebApp.java
package com.dogukanhan.spring101; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan("com.dogukanhan.spring101*") public class WebApp { public static void main(String[] args) { SpringApplication.run(WebApp.class, args); } }
WebMvcConfig.java
package com.dogukanhan.spring101.configuration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.view.ThymeleafViewResolver; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private ApplicationContext applicationContext; @Bean public SpringResourceTemplateResolver templateResolver() { SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setApplicationContext(applicationContext); templateResolver.setPrefix("/WEB-INF/views/"); templateResolver.setSuffix(".html"); templateResolver.setCacheable(false); return templateResolver; } /* * STEP 2 - Create SpringTemplateEngine * */ @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver()); templateEngine.setEnableSpringELCompiler(true); return templateEngine; } /* * STEP 3 - Register ThymeleafViewResolver * */ @Override public void configureViewResolvers(ViewResolverRegistry registry) { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine()); registry.viewResolver(resolver); } }
PersistenceJPAConfig.java
package com.dogukanhan.spring101.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import java.util.Properties; @Configuration @EnableTransactionManagement public class PersistenceJPAConfig { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); em.setPackagesToScan(new String[]{"com.dogukanhan.spring101.entity"}); JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); em.setJpaProperties(additionalProperties()); return em; } @Bean public DataSource dataSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://172.17.0.1:3306/spring101"); ds.setUsername("root"); ds.setPassword("my-secret-pw"); return ds; } @Bean public PlatformTransactionManager transactionManager( EntityManagerFactory emf) { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(emf); return transactionManager; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } Properties additionalProperties() { Properties properties = new Properties(); properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); properties.setProperty( "hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect"); return properties; } }
HomeController.java
package com.dogukanhan.spring101.controller; import com.dogukanhan.spring101.FormCommand; import com.dogukanhan.spring101.entity.Post; import com.dogukanhan.spring101.repository.PostRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import java.util.List; @Controller public class HomeController { @Autowired private PostRepository postRepository; @ModelAttribute("formCommand") public FormCommand formCommand() { return new FormCommand(); } @GetMapping("/") public String index(Model model) { List<Post> posts = postRepository.findAll(); model.addAttribute("posts", posts); return "index"; } @GetMapping("/new") public String newpost(Model model) { List<Post> posts = postRepository.findAll(); model.addAttribute("posts", posts); return "new"; } @PostMapping("/new") public String processSubmit(Model model,@ModelAttribute FormCommand formCommand) { Post post = new Post(); post.setContent(formCommand.getContent()); post.setTitle(formCommand.getTitle()); post.setSender(formCommand.getSender()); postRepository.save(post); model.addAttribute("post",post); return "new"; } @GetMapping("/delete/{id}") public String newpost(Model model, @PathVariable long id) { postRepository.deleteById(id); return "delete"; } }
FormCommand.java
package com.dogukanhan.spring101; public class FormCommand { private String sender, title, content; public String getSender() { return sender; } public void setSender(String sender) { this.sender = sender; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
index.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Spring Example</title> </head> <body> <a th:href="@{/new}"> Create New Post </a> <h2>Posts</h2> <ul> <li th:each="post: ${posts}"> <div th:text="${post.title} +' | ' + ${post.sender} "> Post List</div> <a th:href="@{/delete/}+${post.ID}"> Del </a> </li> </ul> </body> </html>
new.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Spring Example</title> </head> <body> <div th:if="${post}"> <div th:text="'Post is created id = ' + ${post.ID}"> Post is created </div> </div> <div th:unless="${post}"> <form action="#" th:action="@{/new}" th:object="${formCommand}" method="post"> <p>Sender: <input type="text" th:field="*{sender}" /></p> <p>Title: <input type="text" th:field="*{title}" /></p> <p>Content: <textarea th:field="*{content}" ></textarea></p> <input type="submit"/> </form> </div> </body> </html>