Để đơn giản quá trình lập trình ứng dụng với Spring framework, Spring Boot đã được giới thiệu. Các bạn có thể tham khảo bài viết này để hình dung Spring Boot là gì nhé!
Trong bài viết này, mình tổng hợp tất cả những bài viết của Hướng Dẫn Java về Spring Boot để mọi người tiện tham khảo.
Cài đặt
Để có thể tạo mới một project Spring Boot dễ dàng sử dụng command line trên Window, các bạn nên tham khảo bài viết này để cài đặt Spring Boot CLI.
Tương tự như trên Window, các bạn cũng có thể cài đặt Spring Boot CLI trên Ubuntu.
Trong bài viết này, mình hướng dẫn các bạn cách cài đặt Spring Boot CLI trên môi trường macOS.
Tạo mới Spring Boot project
Các bạn có thể tạo mới Spring Boot project sử dụng Spring Initializr Web ở địa chỉ http://start.spring.io/.
Các bạn cũng có thể sử dụng Spring Tool Suite để tạo mới Spring Boot project.
Làm việc với database
Trong bài viết này, mình hướng dẫn các bạn cấu hình database trong Spring Boot với JPA Starter dependency.
Trong bài viết này, mình hướng dẫn các bạn cách sử dụng EclipseLink thay thế Hibernate trong Spring Data JPA Starter.
Mình sẽ hướng dẫn các bạn cách cấu hình multiple Datasources cho ứng dụng Spring Boot trong bài viết này.
Bài viết hướng dẫn
Để hiểu cách hoạt động của Spring Boot, các bạn có thể tham khảo bài viết này.
Trong bài viết này, mình hướng dẫn các bạn làm thế nào để tạo ứng dụng Java console với Spring Boot.
Trong bài viết này, mình hướng dẫn các bạn cách binding properties trong Spring Boot với annotation @ConfigurationProperties.
Các bạn sẽ biết cách cài đặt và sử dụng Apache Title trong Spring Boot nếu đọc bài viết này.
Trong bài viết này, mình sẽ hướng dẫn các bạn cách sử dụng InternalResourceViewResolver trong Spring Boot.
Trong bài viết này, mình sẽ hướng dẫn các bạn cách cấu hình JSP views trong InternalResourceViewResolver với Spring Boot JAR file.
Trong bài viết này, mình hướng dẫn các bạn cách sử dụng Springfox cho Swagger để tạo RESTful API document trong Spring Boot.
Trong bài viết này, mình hướng dẫn các bạn cách tạo RESTful API documentation với thư viện springdoc-openapi trong ứng dụng Spring Boot.
Trong bài viết này, mình hướng dẫn các bạn cách sử dụng Thymeleaf trong Spring Boot.
Trong bài viết này, mình giới thiệu với các bạn về công cụ DevTools trong Spring Boot.
Trong bài viết này, mình giới thiệu với các bạn về Spring Boot Actuator.
Trong bài viết này, mình sẽ hướng dẫn cho các bạn cách viết Unit Test cho Spring Boot application.
Sử dụng Spring Security với Spring Boot, chúng ta sẽ giảm thiểu các bước cấu hình cho Spring Security đi rất nhiều!
Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu về annotation @ConditionalOnBean trong Spring Boot.
Trong bài viết này, mình giới thiệu với các bạn về những support của Spring Boot cho Docker Compose.
Database Migration
Trong bài viết này, mình hướng dẫn các bạn cách sử dụng Liquibase trong Spring Boot.
Trong bài viết này, mình hướng dẫn các bạn cách sử dụng Flyway trong Spring Boot.
Trong bài viết này, mình hướng dẫn các bạn cách cấu hình Flyway với Spring Data R2DBC trong Spring Boot.
Resilience4j
Trong bài viết này, mình hướng dẫn các bạn cách hiện thực Timeout Pattern với thư viện Resilience4j TimeLimiter trong ứng dụng Spring Boot.
gRPC
Trong bài viết này, mình hướng dẫn các bạn cách hiện thực một gRPC server với Spring Boot sử dụng grpc-server-spring-boot-starter.
Deployment
Mình sẽ hướng dẫn các bạn làm thế nào để deploy một ứng dụng Spring Boot lên Cloud Foundry sử dụng Spring Boot Dashboard trong Spring Tool Suite.
Trong bài viết này, mình hướng dẫn các bạn cách đơn giản để deploy ứng dụng Spring Boot trong Docker container.
my
Anh cho em hỏi làm sao upload ảnh lên thư mục của project trong spring boot vậy ạ (ví dụ: src/main/resources/ upload)
Em code như dưới mà nó chỉ lưu ở đường dẫn tạm thôi
// Upload avatar
// Thư mục gốc upload file.
String path = request.getSession().getServletContext().getRealPath(“”);
System.out.println(“uploadRootPath=” + path);
String dirPath = path + File.separator + Defines.DIR_UPLOAD;
System.out.println(“dirPath=” + dirPath);
if (cmf!= null) {
try {
InputStream inputStream = cmf.getInputStream();
if (inputStream == null) {
System.out.println(“File inputstream is null”);
}
File dirFile = new File(dirPath);
// Tạo thư mục gốc upload nếu nó không tồn tại.
if(!dirFile.exists()) {
dirFile.mkdir();
}
String filePath = dirPath + File.separator + cmf.getOriginalFilename();
// Create the file at server
File upload = new File(filePath);
// method transferTo để tiến hành upload file lên server.
cmf.transferTo(upload);
user.setAvatar(cmf.getOriginalFilename());
IOUtils.closeQuietly(inputStream);
} catch (IOException ex) {
System.out.println(“Error saving uploaded file”);
}
}
Khanh Nguyen
Gửi anh project này đi em.
my
project của em đây ạ, em mò mãi mà không ra mong anh xem giúp.
Link trang: https://localhost:30/admin/user/add
Database: src/main/resources/mydatabase.sql
https://drive.google.com/file/d/19K1byfk4nNUnGbRZ5jyATz7GSlmce0Ji/view
my
Em debug thì thấy chỗ avatar.getOriginalFilename() nó ra null vậy là sao vậy anh
Vĩ
em bị lỗi SunCertPathBuilderException: unable to find valid certification path to requested target mỗi lần nhấn vào New->File->New Spring Starter, nó bị v ko tạo project đc a ơi
Khanh Nguyen
Cái này chắc do STS với Java của em có vấn đề gì rồi. Em có cấu hình gì liên quan tới certificate không?
Vĩ
e sửa lỗi đc r mà e gặp lỗi khác
a ơi trong file POM.xml nếu muốn thêm 1 dependencies vào thì mình khai báo
commons-codec
commons-codec
nhưng khi e add vào thì file POM.xml nó không tự download về thì bây h mình phải làm cách nào để add cái thư viện đó vào trong project mình v a?
Khanh Nguyen
Em khai báo cụ thể như thế nào nhỉ? Sau khi add vào file pom.xml thì em có thể click chuột phải vào project chọn Maven rồi chọn Update Project… để Maven update dependencies nhé!
Vĩ
nó báo lỗi vầy nè a, máy trên công ty như chặn proxy ko vô youtube,gmail, hay một số trang web đc nên e nghĩ maven nó cũng bị chặn ko cho down dependencies
Project build error: ‘parent.relativePath’ of POM org.springframework.api:API:0.0.1-SNAPSHOT (D:\DENSHI-WS\API\pom.xml) points at stackjava.com:SpringBootDownloadFile instead of org.springframework.boot:spring-boot-starter-parent, please verify your project structure
Em có nhấn update chục lần cũng ko đc
Khanh Nguyen
Thử chạy mvn clean install dùng command-line xem sao em?
my
Anh ơi cho em hỏi lỗi này
Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ’tilesConfigurer’ defined in class path resource [org/o7planning/webapp/TilesConfiguration.class]: Initialization of bean failed; nested exception is java.lang.TypeNotPresentException: Type org.apache.tiles.preparer.factory.PreparerFactory not present
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:759)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:117)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:689)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:969)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:958)
at org.o7planning.webapp.MainApp.main(MainApp.java:17)
Khanh Nguyen
Bạn gửi Khanh cấu hình của bạn cho Apache Tiles nhé.
my
package org.o7planning.webapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesView;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
public class TilesConfiguration {
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[]{“WEB-INF/tiles.xml”});
configurer.setCheckRefresh(true);
return configurer;
}
@Bean
public TilesViewResolver tilesViewResolver() {
TilesViewResolver resolver = new TilesViewResolver();
resolver.setViewClass(TilesView.class);
return resolver;
}
}
Khanh Nguyen
Bạn làm theo hướng dẫn của Hướng Dẫn Java ở đây thử nhé https://huongdanjava.com/vi/?s=apache+tiles&submit=
Trương Quốc Chiến
Chào bạn Khánh Nguyễn.
Bạn cho mình hỏi 1 câu với. Mình code spring-boot ấy, nếu viết theo kiểu thông thường mình sẽ dùng thymeleaf ở front và với điều này mình có thể sử dụng .html, mình không hiểu tại sao bạn lại sử dụng .jsp nhỉ. Mình chỉ vì đó giờ mình cũng có thắc mắc mà chưa kiếm được cao nhân, mình xin cảm ơn bạn trước.
Những topic của bạn rất bổ ích 🙂
Khanh Nguyen
Về bản chất thì tất cả các file .html hay .jsp đều được xử lý ở phía server trước nên nó như nhau thôi bạn. Chỉ có điều với Thymeleaf thì nó theo kiểu Natural Template, có nghĩa là nhìn khai báo của nó giống các thẻ HTML hơn, còn với file .jsp thì chúng ta có thể khai báo thêm code Java trong đó nữa.
Trương Quốc Chiến
Dear Khánh Nguyễn.
Bạn có thể viết 1 topic về ApplicationEvent của Spring không bạn ? Mình đang tìm hiểu cái đó, không hiểu tại sao lại sử dụng, mình chỉ biết nó cung cấp asyn vs syn, nhưng đọc mãi không hiểu lý do khi nào sử dụng ? Mình cũng đam mê spring, mình có thể kết bạn và trao đổi kiến thức với nhau được không nhỉ ?
Vo_Bk
Hi khánh, trợ giúp nhiệt tình quá, Triệu like cho bạn
Khanh Nguyen
Thank bạn. 😀
Hải
Dear Khanh Nguyen,
Vì mình có đọc hướng dẫn của bạn chỉ spring boot tự động quét các gói cùng cấp và các gói bên trong nó cùng với gợi ý mới nhất của bạn nên mình nghĩ có lẽ tên các gói mình đã ghi sai tên các gói và đúng mình ghi sai thật. Cám ơn Bạn rất nhièu.
Hải
Dear Khanh Nguyen.
Mình đã cố hết sức rồi mà không xử lý được, mong Bạn giúp mình với
Khanh Nguyen
Gửi qua mail cho mình đi bạn: huongdanjava.com@gmail.com
Hải
Deâr Khanh Nguyen,
Dia chi mail này huongdanjava.com@gmail.com không gử được. Mình cũng đã thử với địa chỉ huongdanjava@gmail.com cũng không được luôn. Không hiểu có phải do net có vấn đề không.
Khanh Nguyen
Do network của bạn đó, chứ mình đăng nhập huongdanjava.com@gmail.com cái này bình thường.
Hải
Dear Khanh Ngyen,
Google nó báo không cho gửi tập tin nén đuôi rar. Nó bảo đưa lên google driver: Mình đưa lên đó rồi gửi link bạn giúp mình downlad từ link này được không
https://drive.google.com/file/d/0B3I6-i_D1Xy3RGJ3SDhNaXN3RGM/view?usp=sharing
Cám ơn nhiều.
Khanh Nguyen
Hi bạn, mình đã tìm ra vấn đề bạn đang gặp phải!
Vấn đề là các class HelloWorldController và WebMvcConfig không được Spring Boot tự động scan. Bạn đã để các class này nằm khác package với class HelloSpringBootApplication.
Để Spring Boot tự động scan, hoặc là bạn move những class này vào chung package với class HelloSpringBootApplication hoặc là bạn phải khai báo thêm tên package của những class này sử dụng thuộc tính scanBasePackageClasses trong annotation @SpringBootApplication như sau:
@SpringBootApplication(scanBasePackageClasses = { WebMvcConfig.class, HelloWorldController.class } )
Có gì thắc mắc cứ hỏi tiếp nhé!
Hải
Dear Khanh vì khong còn chỗ reply nên mình đành đưa vào đây. Mình đã làm theo gợi ý của bạn thêm “/” vào trước như này
resolver.setPrefix(“/WEB-INF/pages/”); nhưng nó vẫn không tìm thá jsp file của mình. Mình đã cố gắng search trên net xem họ làm như nào nhưng thử làm vẫn không được. Có câu hỏi gần như tương tự trên stackoverflow : https://stackoverflow.com/questions/43757695/spring-boot-jsp-files-cannot-be-found
nhưng vẫn không giải quết được vf các cấu trúc thư mục mình đặt tên đúng . Mong bạn gỡ giúp mình chỗ này. Xin cảm ơn rất nhiều
Khanh Nguyen
Đưa mình lại project đi bạn! Bỏ mấy thứ liên quan đến database để mình có thể chạy không cần setup gì cả nhé!
Bạn nên up project lên google drive và share link cho mình 😀
Hải
https://drive.google.com/file/d/0B3I6-i_D1Xy3RGJ3SDhNaXN3RGM/view?usp=sharing
Cám ơn Bạn.
Khanh Nguyen
Rất xin lỗi bạn là hiện tại laptop mình đang đem đi bảo hành nên không có máy để làm gì cả.
Vấn đề của bạn không biết giờ mình phải support bạn bằng cách nào nữa. Giờ bạn thử giải quyết tiếp xem được không nhé!
Nếu thứ 2 mà bạn vẫn không giải quyết được thì gửi mail cho mình. Khi nào lên công ty, có máy tính mình sẽ giúp bạn.
Hải
Cảm ơn Khanh Nguyen rất nhiều.
Hải
Cám ơn Bạn đã phản hồi. Một ví dụ tương tự như trên nhưng mình đã bổ sung phần View, Run as bằng spring đã không báo lỗi nhưng khi gõ http://localhost:8080/contactList thì nó báo lỗi Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Aug 30 11:02:54 ICT 2017
There was an unexpected error (type=Not Found, status=404).
No message available
Mình xin được post ví dụ ở đây: http://www.mediafire.com/file/11bc286147t7b7p/spring-mycontact-master.zip
Mong bạn coi giúp mình. Cho mình hỏi thêm là khi dùng netbean thì thêm file javacrip(js) vào thư mực mình muốn được. Trong Eclipse thì không biết thêm vào như thế nào bạn chỉ giúp mình với. Cám ơn Bạn nhiều
Khanh Nguyen
Khanh không thấy bạn định nghĩa cái request “/contactList” trong code?
Về câu hỏi thứ hai, Khanh nghĩ cái này là Maven project thì nó không phụ thuộc vào IDE đâu bạn. Trên Netbean sao thì Eclipse bạn để y vậy là được.
Hải
Dear Khanh,
Mình có định nghĩa trong controller:
package com.yuen.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.yuen.domain.Contact;
import com.yuen.service.ContactService;
@Controller
public class ContactController {
@Autowired
private ContactService contactService;
@GetMapping(“/contactList”)
public String index(Model model) {
model.addAttribute(“listContact”, contactService.findAll());
return “contactList”;
}
}
Không biết như này đúng không. Về câu hỏi thứ 2 thì như Bạn nói mình đã làm theo và ok. Thanks Bạn
Khanh Nguyen
Sao cái project mình thấy nội dung khác nhỉ?
Với định nghĩa trên, mình chỉ phân vân chỗ return lại contactList thì bạn đang dùng template nào để render phần view? Còn lại thì mình thấy OK.
Nếu có lỗi thì bạn đưa mình xem thử bị lỗi gì nhé!
Hải
Dear Khanh,
Mình xin lỗi đã cập nhật nhầm ví dụ, Cho phép mình cập nhật lại link http://www.mediafire.com/file/jcdc1773iifenh4/spring-mycontact-master.rar
Chỗ định nghĩa url là controler
@Controller
public class ContactController {
@Autowired
private ContactService contactService;
@GetMapping(“/contactList”)
public String index(Model model) {
model.addAttribute(“listContact”, contactService.findAll());
return “contactList”;
}
}
Chỗ định template cho view là gói config:
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(“WEB-INF/pages/”);
resolver.setSuffix(“.jsp”);
return resolver;
}}
Một lần nữa rất xin lỗi bạn vì sự nhầm lẫn.
Khanh Nguyen
Hiện tại vẫn đang bị lỗi ko truy cập được vào “/contactList” hả bạn?
Theo Khanh thấy thì dòng code sau:
resolver.setPrefix("WEB-INF/pages/");
nên thêm dấu “/” vào ở đầu “WEB-INF/pages”. Thành:
resolver.setPrefix("/WEB-INF/pages/");
TùngMP
Hi Hải, theo mình thì đây là lỗi liên quan đến thẻ trong file html (layout.html) nằm ở templates, hãy thử sử dụng và để thay thế cho và (bạn có thể test trước phán đoán của mình bằng cách loại các thành phần “th:replace=”layout :: …” ” ra khỏi file list.html và test thử). Còn 1 ý nữa là return của bạn phải trả về list chứ ko phải contactList. Hy vọng nó có thể giúp cho bạn!
Khanh Nguyen
Hi Tùng,
Khanh đã tìm ra nguyên nhân lỗi mà Hải đang gặp phải. Tùng có thể xem thêm comment ở trên nhé!
Zoro
bạn đã fix được lỗi này chưa, mình cũng đang gặp lỗi tương tự mà mãi chưa fix được
Khanh Nguyen
Khanh đã tìm ra nguyên lỗi của Hải rồi, bạn có thể xem thêm để tham khảo nhé!
Hải
MÌnh học theo bài viết cảu bạn làm cái ví dụ này nhưng không hiểu sao nó báo lỗi. “Field invItemTypeService in com.vta.spm.controller.inv.INV_ItemTypeController required a bean of type ‘com.vta.spm.service.inv.INVItemTypeService’ that could not be found.” Mình nghĩ do cấu trúc thư ục và file có vấn đề nên nó scan không thấy nhưng đã kiểm tra lại thấy hơp lý. Mình post lên đây mong bạn coi giúp http://www.mediafire.com/file/p727o78874l95tn/spm.rar(chưa có view). Cám ơn Bạn nhiều.
Khanh Nguyen
Bạn đang declare class INVItemTypeServiceImpl là abstract class. Abstract class thì không thể khởi tạo đối tượng, đó là nguyên nhân Spring Boot ko tìm thấy bean cho interface INVItemTypeService.
Có gì bạn cứ hỏi rồi discuss tiếp nhé!
Hoàng
anh ơi nếu chúng ta muốn up một project của mình đang k sử dụng spring boot thành sử dụng spring boot thì cần làm những gì a
Khanh Nguyen
Tuỳ theo project của em sử dụng công nghệ gì rồi mình suy nghĩ giải pháp thôi em, không khó để chuyển qua Spring Boot đâu.
DanhLT
Anh ơi cứu em cái lỗi này với … chết mất 🙁
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘tomcatEmbeddedServletContainerFactory’ defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration’: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘spring.http.encoding-org.springframework.boot.autoconfigure.web.HttpEncodingProperties’: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl
Khanh Nguyen
Bạn gửi project cho mình được không?
DanhLT
Dạ đây nè anh. Em sử dụng IDE eclipse nha anh… https://drive.google.com/open?id=0B59t5V-EmbGveVlLSXgtMDVxRUU
DanhLT
Anh ơi e sửa thành công rồi ^^! 😀
Khanh Nguyen
Chúc mừng bạn, 😀 Có gì khó khăn cứ liên hệ Hướng Dẫn Java nhé!