วันอังคารที่ 7 กรกฎาคม พ.ศ. 2558

ทำให้ Spring Boot Reload บน Eclipse

ปกติเราจะรันผ่าน Command line โดยใช้ Maven รัน มาตอนนี้ลองรันผ่าน Eclipse กันบ้าง (ตัวอ่นก็ใช้ได้นะครับ)
1. จะรันเหมือน Java Class ปกติ ครับ โดยสั่งให้ไปรันที่ Class ที่เราไว้ Start Spring Boot นั่นเอง (Run As..)

2. เผอิญ Eclipseไม่ฉลาดเลยจะไม่เห็นส่วนของ src/main/resources เราจะต้องแอดไปเองในส่วนของ Class Path
3. ต่อไปก็สั่งรันได้แล้วครับ

เพิ่มเติมสำหรับคนอยา่ให้มัน Reladed อัติโนมัตหลังแก้ ให้เพิ่ส่วนของ Spring Loaded ไปตามนี้ครับ
เพิ่มส่วนของ Argument
-javaagent:springloaded-1.2.3.RELEASE.jar -noverify



วันจันทร์ที่ 29 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 9 มาสร้าง Banner กัน

มาสร้าง Banner ลงบน Application ตอนเรา Start กันครับ
มันคือส่วนนี้




เราสามารถเปลี่ยนง่ายโดยการเพิ่ม banner.txt ไว้ที่ src/main/resources ครับ ก็จะได้ใช้ได้เลย
สามารถใช้เวบนี้ สร้างภาพได้ http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Demo%20Spring%20Boot

ส่วนสามารถปิดเปิด Banner ได้โดยการเพิ่มค่าใน application.properties

spring.main.show-banner=true
 

วันเสาร์ที่ 20 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 8 Testing

ต่อไปมาดูว่าเราจะเทสกันยังไงครับ ถ้าเป็น Unit Testing ไม่ใช่ส่วนของ Controller กับ Repository น่าจะเเขียนเทสได้เลยโดยไม่ต้องพึ่ง Spring-Test สกับพวก Integration Testing ก็ต้องใช้ Spring-Test ล่ะครับ
เรามาดูกัน
1. Config POM
 <dependency>  
      <groupId>org.springframework.boot</groupId>  
      <artifactId>spring-boot-starter-test</artifactId>  
      <scope>test</scope>  
 </dependency>  
     โดยมันจะดึง Library Spring Test, JUnit, Hamcrest, Mockito มาให้เลยครับ

2. ถาจะทำเทสจะต้องมี embedded server มาด้วยนะครับ เพราะถ้าเขียนลง Server จะ exclude ออก ถ้าจะเทสจะเอาเข้ามาแล้วใช้ Scope = test เอาครับ แบบนี้
 <dependency>  
      <groupId>org.springframework.boot</groupId>  
      <artifactId>spring-boot-starter-tomcat</artifactId>  
      <scope>provided</scope>  
 </dependency>  

3. มาดู Class Test
 package tutorialspring4.controllers;  
 import static org.hamcrest.Matchers.is;  
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;  
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;  
 import org.junit.Before;  
 import org.junit.Ignore;  
 import org.junit.Test;  
 import org.junit.runner.RunWith;  
 import org.springframework.boot.test.SpringApplicationConfiguration;  
 import org.springframework.http.MediaType;  
 import org.springframework.mock.web.MockServletContext;  
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
 import org.springframework.test.context.web.WebAppConfiguration;  
 import org.springframework.test.web.servlet.MockMvc;  
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;  
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;  
 import tutorial.spring4.controllers.HelloController;  
 import tutorial.spring4.forms.HelloForm;  
 @RunWith(SpringJUnit4ClassRunner.class)  
 @SpringApplicationConfiguration(classes = MockServletContext.class)  
 @WebAppConfiguration  
 public class HelloControllerTest {  
      private MockMvc mvc;  
      @Before  
      public void setUp() throws Exception {  
           mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();  
      }  
      @Test  
      public void getHello() throws Exception {  
           HelloForm form = new HelloForm();  
           form.setSay("Hi");  
           form.setName("Hello");  
           mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())  
           .andExpect(jsonPath("$.say", is(form.getSay()))).andExpect(jsonPath("$.name", is(form.getName())));  
      }  
 }  
     - RunWith = SpringJUnit4ClassRunner บอก JUnit ว่าจะใช้ Spring Test
     - SpringApplicationConfiguration = MockServletContext บอก Spring ว่าจะใช้ Mock ส่วนของ servlet
     - MockMvc จะ Mock ส่วนของ Controller เพื่อเทส จะเห็นว่าตอน SetUp จะมีการ Build อยู่
     - ส่วนเทสจะเห็นว่าเทสไปที่ Path เลยไม่ได้เทส จาก Controller ทำให้เทส route ว่าถูกไหม ทำงานโอเคไหมครับ

References
Basic
1. Spring Boot ตอนที่ 1 มาทำความรู้จักกับ Spring Boot
2. Spring Boot ตอนที่ 2 Hello World
3. Spring Boot ตอนที่ 3 โครงสร้างของ Project
4. Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf
5.Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]
6.Spring Boot ตอนที่ 6 กับ Production Database
7.Spring Boot ตอนที่ 7 Security
8.Spring Boot ตอนที่ 8 Testing

วันศุกร์ที่ 19 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 7 Security

Spring Boot ก็ใช้ Spring Security ครับ ซึ่งก็ทำง่ายมาก แต่หันมาใช้การ Config ผ่าน Annotation และก็เขียนคลาสหมดไม่ได้ใช้ XML แล้วครับ ซึ่งอาจจะดูแปลกตาสำหรับคนที่ใช้ XML พอสมควร งั้นมาเริ่มกันเลย
1. Config POM เพิ่ม
 <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-starter-security</artifactId>  
</dependency>  

2. ต่อไปก็ EnableWebSecurity
 package tutorial.spring4;  
 import javax.annotation.Resource;  
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.context.annotation.Configuration;  
 import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;  
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
 import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;  
 import org.springframework.security.core.userdetails.UserDetailsService;  
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
 import org.springframework.security.crypto.password.NoOpPasswordEncoder; 
 
 @Configuration  
 @EnableWebMvcSecurity  
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
      @Resource(name="basicUserDetailService")  
      private UserDetailsService userDetailsService;  
      @Override  
      protected void configure(HttpSecurity http) throws Exception {  
           http.authorizeRequests().antMatchers("/hello").permitAll().anyRequest().authenticated().and()  
                     .formLogin().loginPage("/login").failureUrl("/login?error").defaultSuccessUrl("/loginresult", true).permitAll()  
                     .and().logout().permitAll();  
      }  
      @Override  
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {  
           auth.userDetailsService(userDetailsService).passwordEncoder(new PlaintextPasswordEncoder());  
      }  
 }  
     แบบนี้เป็น Config ให้ใช้ UserDetailService ที่คุ้นเคย โดยเราจะเห็นว่า Class นี้เป็น Config และบอกให้ Enable Web Security ด้วย และ extends WebSecurityConfigurerAdapter มีสองตัวหลักๆ
     - Method แรก สำหรับที่เรา Config Route ที่เคยเห็นๆ บน XML อันนี้ยกมาบน Class สำหรับผ่านง่ายขึ้น อธิบายคร่าวๆ
          - antmatches คือตรงกับอันนี้ จะทำอะไรอ่านข้างหลัง permitAll คือเข้าได้หมด อันอื่นๆ anyRequest ต้องมี Authen พอทำเสร็จ
          - ส่วนของหน้า Login ใช้ formLogin ด้วยหน้าอะไร ถ้า fail ไปไหน สามารถกำหนดได้ว่า ถ้า login ให้กลับไปหน้าเก่าที่เราเข้ามาได้ด้วยนะครับ
     - Method ที่สอง หลักๆ ไว้สำหรับเรื่องว่าจะ authen แบบไหนมี่ทั้ง JDBC/LDAP/ InMemory

3. แค่นี้ก็เป็นอันเสร็จเรียบร้อยแล้วครับ

References
Basic
1. Spring Boot ตอนที่ 1 มาทำความรู้จักกับ Spring Boot
2. Spring Boot ตอนที่ 2 Hello World
3. Spring Boot ตอนที่ 3 โครงสร้างของ Project
4. Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf
5.Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]
6.Spring Boot ตอนที่ 6 กับ Production Database
7.Spring Boot ตอนที่ 7 Security
8.Spring Boot ตอนที่ 8 Testing

วันพุธที่ 17 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 6 กับ Production Database

มาต่อกันที่ถ้าเราจะใช้ Database ที่เป็น External กันบ้างจะทำยังไงครับ
1. Config POM เหมือนกับ อันที่แล้ว เลย
 <dependency>  
      <groupId>org.springframework.boot</groupId>  
      <artifactId>spring-boot-starter-data-jpa</artifactId>  
 </dependency>  

2. เพิ่ม Library สำหรับ Connect Database ที่ต้องการ

3. ต่อไป Config เพิ่มใน application.properties ต่อไปเป็นตัวอย่างที่ใช้ประจำครับ มีเพิ่มเติมสามารถไปดูได้ที่ Spring Boot Reference ครับ
 spring.datasource.url=jdbc:mysql://localhost/springboot  
 spring.datasource.username=root  
 spring.datasource.password=password1  
 spring.datasource.driver-class-name=com.mysql.jdbc.Driver  
 spring.jpa.hibernate.ddl-auto=update  
 spring.jpa.open-in-view=true  
 spring.jpa.show-sql=true  
 spring.datasource.initialize=true
     - spring.datasource.url = URL ติดต่อ Database
     - spring.datasource.username = Username ติดต่อ Database
     - spring.datasource.password = Password ติดต่อ Database
     - spring.datasource.driver-class = Driver ต่อต่อ Database
     - ถ้าจะติดต่อผ่าน JNDI ให้ใช้ spring.datasource.jndi-name
     - spring.jpa.hibernate.ddl.auto =  กำหนดว่าจะสร้าง ลบ หรืออัพเดทก่อนไหม
     - spring.jpa.open-in-view = สำหรับให้สามารถดึงข้อมูลตอนอยู่บนหน้าจอได้ มันคือ SessionInView
     - spring.jpa.show-sql = จะให้เห็น SQL ไหม
     - spring.datasource.initialize ให้อ่านค่า data.sql

4. ตอนนี้ Spring Boot รู้ล่ะว่าใช้งาน Spring Data JPA
5. สร้าง Entity ขึ้นมาเพื่อลองใช้งาน

 package tutorial.spring4.entities;  
 import java.io.Serializable;  
 import javax.persistence.Column;  
 import javax.persistence.Entity;  
 import javax.persistence.Id;  
 import javax.persistence.Table;  
 @Entity  
 @Table(name = "AUTHOR")  
 public class Author implements Serializable {  
      @Id  
      @Column(name = "AUTHOR_CODE")  
      private String authorCode;  
      @Column(name = "FIRST_NAME")  
      private String firstname;  
      @Column(name = "LAST_NAME")  
      private String lastname;  
      public String getFirstname() {  
           return firstname;  
      }  
      public void setFirstname(String firstname) {  
           this.firstname = firstname;  
      }  
      public String getLastname() {  
           return lastname;  
      }  
      public void setLastname(String lastname) {  
           this.lastname = lastname;  
      }  
      public String getAuthorCode() {  
           return authorCode;  
      }  
      public void setAuthorCode(String authorCode) {  
           this.authorCode = authorCode;  
      }  
 }  

6. ลอง start ดูครับ จะเห็นว่ามีการสร้าง Table นี้ขึ้นมาให้เลย

7. ต่อไปสร้าง @Repository
 package tutorial.spring4.repositories;  
 import org.springframework.data.jpa.repository.JpaRepository;  
 import tutorial.spring4.entities.Author;  
 public interface AuthorRepository extends JpaRepository<Author, String> {  
 }  

8. สามารถใช้งานได้แล้ว ส่วนการใช้งาน Spring Data JPA เดี๋ยว ผมเพิ่มให้แยกส่วนนะครับ เพราะตรงส่วนนั้นก็เยอะเหมือนกัน

PS. ถ้าอยากให้มีการ Initialize ค่า สามารถใช้ data.sql สร้าง SQL Insert ก่อนได้ครับ โดยไว้ที่ src/main/resources ครับ

References
Basic
1. Spring Boot ตอนที่ 1 มาทำความรู้จักกับ Spring Boot
2. Spring Boot ตอนที่ 2 Hello World
3. Spring Boot ตอนที่ 3 โครงสร้างของ Project
4. Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf
5.Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]
6.Spring Boot ตอนที่ 6 กับ Production Database
7.Spring Boot ตอนที่ 7 Security
8.Spring Boot ตอนที่ 8 Testing

วันพุธที่ 10 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]

     โดยปกติเวลาเราใช้ Spring เราก็จะใช้ hibernate ใช่ไหมครับในการติดต่อฐานข้อมูล ซึ่ง Spring Boot ก็มีมาให้โดยใช้ Spring Data JPA ในการติดต่อฐานข้อมูล
     ข้อดีของมันคืออะไร คือเราสามารถเขียนเป็นภาษาคนในการดึงข้อมูลได้เลย และตัวมัน provide iinterface หลายๆ อย่างให้พอสมควร
     ตัวอย่างการดึงข้อมูล findByFirstnameOrderByCreateDateDesc หมายถึงดึงข้อมูลจาก Column Name = firstname โดยดึงมาแล้วเรียงด้วย CreateDate แบบ Desc
     ต่อไปส่วนของ Spring Boot ได้เตรียมการติดต่อฐานข้อมูลแบบ Embedded Database ไว้แค่เราบอกว่าใช้ โดยมี H2, HSQL, Derby
     เรามาดูส่วนของการใช้งาน Embeded กันก่อนนะครับ ซึ่งถ้าจะใช้ External Database ก็แค่เพิ่ม config ใน application.properties เท่านั้น

1. เพิ่มข้อมูลใน pom.xml ว่าจะใช้ Spring-data-jpa กับจะใช้ Database อะไร
 <dependency>  
   <groupId>org.springframework.boot</groupId>  
   <artifactId>spring-boot-starter-data-jpa</artifactId>  
 </dependency>  
 <dependency>  
   <groupId>org.hsqldb</groupId>  
   <artifactId>hsqldb</artifactId>  
   <scope>runtime</scope>  
 </dependency>  
     - dependency อันแรกหมายถึงจะใช้ spring-data-jpa
     - dependency อันที่สองหมายถึงจะใช้กับ Hsql นะ

2. เรามาลองสร้าง Entity สร้างปกติเลยครับ
 package tutorial.spring4.entities;  
 import java.io.Serializable;  
 import javax.persistence.Column;  
 import javax.persistence.Entity;  
 import javax.persistence.Id;  
 import javax.persistence.Table;  
 @Entity  
 @Table(name = "AUTHOR")  
 public class Author implements Serializable {  
      @Id  
      @Column(name = "AUTHOR_CODE")  
      private String authorCode;  
      @Column(name = "FIRST_NAME")  
      private String firstname;  
      @Column(name = "LAST_NAME")  
      private String lastname;  
      public String getFirstname() {  
           return firstname;  
      }  
      public void setFirstname(String firstname) {  
           this.firstname = firstname;  
      }  
      public String getLastname() {  
           return lastname;  
      }  
      public void setLastname(String lastname) {  
           this.lastname = lastname;  
      }  
      public String getAuthorCode() {  
           return authorCode;  
      }  
      public void setAuthorCode(String authorCode) {  
           this.authorCode = authorCode;  
      }  
 }  

3. ถ้าจะใส่ค่าเริ่มต้นลงในฐานข้อมูลก็ใช้ data.sql ไว้ที่ src/main/resources ครับ เป็น sql Insert ข้อมูลลงฐานข้อมูลให้

4. สร้าง Repository ไว้ process กับฐานข้อมูล
 package tutorial.spring4.repositories;  
 import org.springframework.data.jpa.repository.JpaRepository;  
 import org.springframework.data.jpa.repository.support.JpaEntityInformation;  
 import tutorial.spring4.entities.Author;  
 public interface AuthorReporsitory extends JpaRepository<Author, String>{  
 }  

5. ตอนนี้ก็เรียกใช้งานได้แล้วครับ

References
Basic
1. Spring Boot ตอนที่ 1 มาทำความรู้จักกับ Spring Boot
2. Spring Boot ตอนที่ 2 Hello World
3. Spring Boot ตอนที่ 3 โครงสร้างของ Project
4. Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf
5.Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]
6.Spring Boot ตอนที่ 6 กับ Production Database
7.Spring Boot ตอนที่ 7 Security
8.Spring Boot ตอนที่ 8 Testing


วันจันทร์ที่ 8 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf

     เรามาพูดกันที่ส่วนของการทำ Web Framework กันครับ ซึ่ง Spring Boot มีให้เลือกใช้หลายตัวพวก Template Engine ทั้งหลาย Free Maker, Groovy, Velocity, Thymeleaf
     แล้วทำไมผมถึงเลือกใช้ Thymeleaf ล่ะ เพราะมันคือการเพิ่ม tag พิเศษของ Thymeleaf เองเข้าไปใน HTML Page เลยทำให้สามารถทำหน้า Mock Up นั้นมาใส่ข้อมูลเพิ่มได้เลย ถ้าไม่รันผ่าน Thymeleaf ก็จะเห็นเป็น HTML ธรรมดาแต่พอผ่าน Thymeleaf ก็จะเห็นที่เราใช้ขึ้นมา เราเพิ่มเพียงแค่ th:xxx ใน html tag เท่านั้น
     เรามาดูการ Config กันครับ
1. Config ให้ Spring Boot รู้จัก Thymeleaf โดยเพิ่ม spring-boot-starter-thymeleaf มาใน pom.xml
 <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-thymeleaf</artifactId>  
           </dependency>  

2. ใช้งานได้แล้ว ต่อไปเรามาทำส่วนของ Controller กันต่อ
 package tutorial.spring4.controllers;  
 import org.slf4j.Logger;  
 import org.slf4j.LoggerFactory;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.ui.Model;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RequestMethod;  
 import tutorial.spring4.forms.HelloForm;  
 @Controller  
 @RequestMapping(value="/thymeleaf")  
 public class ThymeleafController {  
      private final static Logger LOG = LoggerFactory.getLogger(ThymeleafController.class);  
      @RequestMapping(method=RequestMethod.GET)  
      public String getPage(final Model model) {  
           LOG.debug("getPage(final Model model)");  
           HelloForm form = new HelloForm();  
           form.setSay("Hi");  
           form.setName("Thymeleaf");  
           model.addAttribute("thymeleaf", form);  
           return "thymeleaf";  
      }  
 }  
     จะเห็นว่าเขียนเหมือน Spring Controller ปกติเลย โดยตอน return จะถูก Mapping ด้วย /src/main/resources/templates/thymeleaf.html จะเติมให้โดยอัติโนมัติโดยไม่ต้อง Config เพิ่มเติมอะไร
     ส่วน model.addAtribute("thymeleaf", form) เราจะเอาไปใช้กับหน้าจอโดยเรียก thymeleaf

3. ต่อไปในส่วนของหน้าเวบ เราจะสร้าง thymeleaf.html โดยไปไว้ที่ src/main/resources/templates
 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:th="http://www.thymeleaf.org"  
    th:include="template :: page">  
   <head>  
     <title>Hello World Spring Boot</title>  
           <!-- initialize the pickers -->  
   </head>  
   <body>  
        <div class="starter-template" th:fragment="content">  
                 <form class="form-inline" role="form" th:object="${thymeleaf}">  
                 <div class="form-group">  
                  <label>Say : </label>  
                  <input type="text" id="hello" th:field="*{say}"/>  
                 </div>  
                 <div class="form-group">  
                  <label>Name : </label>  
                  <input type="text" id="hello" th:field="*{name}"/>  
                 </div>  
                 <button type="submit" class="btn btn-default">Submit</button>  
                </form>  
        </div>  
   </body>  
 </html>  
     - th:include คือการทำส่วนของ template โดยดึง template.html มาในส่วนของ page
     - th:fragment คือส่วนที่เราจะบอกว่าส่วนนี้ให้เอาหน้านี้มาใช้แสดงใน template
     - th:object เป็นการ Mapping Object กับ Form ของหน้าจอ
     - th:field จะ Mapping กับ field ของ thymeleaf ที่เป็น Object ของ HelloForm เช่น th:field="*{say}" จะถูก Mapping กับ field name = "say"

4. แค่นี้เราก็ใช้งานได้แล้วครับ โดยเรียกจาก /thymeleaf ที่ถูก Mapping ใน Controller

References
Basic
1. Spring Boot ตอนที่ 1 มาทำความรู้จักกับ Spring Boot
2. Spring Boot ตอนที่ 2 Hello World
3. Spring Boot ตอนที่ 3 โครงสร้างของ Project
4. Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf
5.Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]
6.Spring Boot ตอนที่ 6 กับ Production Database
7.Spring Boot ตอนที่ 7 Security
8.Spring Boot ตอนที่ 8 Testing