Quick Guide Spring
Quick Guide Spring
Quick Guide Spring
Project CRUD
Initial Project
1. buat project spring dengan menggunakan spring initializr https://start.spring.io/
2. Pilih Spring boot (2.7.5)
3. Pilih Project, untuk management build yg akan digunakan (Pilih Maven)
4. Pilih Language, bahasa pemograman yg akan digunakan (Pilih Java)
5. Isi Informasi Project
- Group, untuk base package
- Artifact, untuk nama folder project
- Name, untuk nama dari project biasanya sama dengan Artifact
- Description, untuk deskripsi dari project
- Package name, review dari package name yg akan di generate
6. Pilih Packaging (pilih war)
- Jar, untuk aplikasi console, lib, desktop
- War, untuk aplikasi web
7. Pilih Java Version, versi java yg akan digunakan (Pilih 11)
*pilih versi lebih rendah dari versi java yg terinstall
8. Tambah Dependency isi dengan
- Spring Web, library untuk membuat aplikasi web
- Spring Boot Dev Tools, library untuk memudahkan ketika perlu merestart aplikasi ketika ada
perubahan
- Thymeleaf, library untuk UI
- Spring Data JPA, library untuk akses data ke Database
9. Klik Generate
Config file
Isi file application.properties dengan data seperti dibawah :
server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/db_demo
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto = update
In Spring/Spring-Boot, SQL database can be initialized in different ways depending on what your
stack is.
JPA has features for DDL generation, and these can be set up to run on startup against the
database. This is controlled through two external properties:
create – Hibernate first drops existing tables, then creates new tables
update – the object model created based on the mappings (annotations or XML) is compared
with the existing schema, and then Hibernate updates the schema according to the diff. It
never deletes the existing tables or columns even if they are no more required by the
application
create-drop – similar to create, with the addition that Hibernate will drop the database after all
operations are completed. Typically used for unit testing
validate – Hibernate only validates whether the tables and columns exist, otherwise it throws
an exception
none – this value effectively turns off the DDL generation
Spring Boot internally defaults this parameter value to create-drop if no schema manager has been
detected, otherwise none for all other cases.
Cara Deploy
1. Update main class (NamaProjectApplication.java)
Contoh :
@SpringBootApplication
public class DemoThymeleafApplication extends SpringBootServletInitializer{
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return builder.sources(DemoThymeleafApplication.class);
}
}
2. Pada pom.xml tambah code di bawah pada bagian build
<build>
<finalName>${artifactId}</finalName>
…
3. Buat war file, dengan menjalankan command
Mvn clean package
4. Deploy ke tomcat
Open manager gui -> deploy -> restart tomcat
Aplikasi CRUD
Referensi : https://www.baeldung.com/spring-boot-crud-thymeleaf
1. Buat package controller, model, repositories
2. Tambah anotasi ini di main class
@EnableAutoConfiguration
@ComponentScan(basePackages={"com.sample.crud"})
@EnableJpaRepositories(basePackages="com. sample.crud.repositories")
@EnableTransactionManagement
@EntityScan(basePackages="com.sample.crud.entities")
3. Buat class model
Contoh :
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
}
Tambahkan dependency Javax.validation untuk anotasi @NotBlank
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
4. Buat Interface Repository, untuk proses crud dasar sudah di implementasikan oleh
CrudRepository
@Repository
public interface UserRepository extends CrudRepository<User, Long>{
}
5. Buat Controller
@Controller
public class UserController {
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/signup")
public String showSignUpForm(User user) {
return "add-user";
}
@PostMapping("/adduser")
public String addUser(@Valid User user, BindingResult result, Model model) {
if (result.hasErrors()) {
return "add-user";
}
userRepository.save(user);
return "redirect:/userScreen";
}
@GetMapping("/userScreen")
public String showUserList(Model model) {
model.addAttribute("users", userRepository.findAll());
return "user";
}
@GetMapping("/edit/{id}")
public String showUpdateForm(@PathVariable("id") long id, Model model) {
User user = userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
model.addAttribute("user", user);
return "update-user";
}
@PostMapping("/update/{id}")
public String updateUser(@PathVariable("id") long id, @Valid User user,
BindingResult result, Model model) {
if (result.hasErrors()) {
user.setId(id);
return "update-user";
}
userRepository.save(user);
return "redirect:/userScreen";
}
@GetMapping("/delete/{id}")
public String deleteUser(@PathVariable("id") long id, Model model) {
User user = userRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
userRepository.delete(user);
return "redirect:/userScreen";
}
*Tambah atribute userRepository yyg bertipe UserRepository, tambahkan juga contruktor untuk
mengisi variable userRepository dengan menggunakan @Autowired
6. Buat file view/tampilan
File add-user.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="#" th:action="@{/adduser}" th:object="${user}" method="post">
<label for="name">Name</label>
<input type="text" th:field="*{name}" id="name" placeholder="Name">
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span>
<label for="email">Email</label>
<input type="text" th:field="*{email}" id="email" placeholder="Email">
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></span>
<label for="email">Password</label>
<input type="password" th:field="*{password}" id="email" placeholder="Password">
<span th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></span>
AUTHENTIFICATION
Referensi : https://www.codejava.net/frameworks/spring-boot/user-registration-and-login-tutorial
1. Tambahkan dependency spring security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. Tambahkan BCryptPassword encoder ketika add user
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
3. Buat Class CustomUserDetails dengan mengimplement class UserDetails dari Spring security
public class CustomUserDetails implements UserDetails {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return user.getPassword();
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
4. Buat package service dan buat class dengan mengimplement UserDetailsService dari Spring
Security
public class CustomUserDetailService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
User user = userRepository.findByEmail(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new CustomUserDetails(user);
}
}
5. Buat method findByEmail di repository
@Query("SELECT u FROM User u WHERE u.email = ?1")
public User findByEmail(String email);
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailService();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService());
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/userScreen").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login") // custom page login
.usernameParameter("email") // muse be same with login field
.defaultSuccessUrl("/userScreen")
// .failureUrl("/pages-login.html?error=true")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")) // for logout
.logoutSuccessUrl("/")// url after logout success
.permitAll();
return http.build();
}
LOGGER
Referensi: https://www.baeldung.com/spring-boot-logging
1. Tambah config logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="./logs" />
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg
%n%throwable
</Pattern>
</layout>
</appender>
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
</configuration>
2. Tambah logger pada bagian yg diinginkan biasa nya pada exception
Logger logger = LoggerFactory.getLogger(LoginController.class);
logger.info("Ist Massage");
public ExcelUtil() {
workbook = new XSSFWorkbook();
}
private void createCell(Row row, int columnCount, Object value, CellStyle style) {
sheet.autoSizeColumn(columnCount);
Cell cell = row.createCell(columnCount);
if (value instanceof Integer) {
cell.setCellValue((Integer) value);
} else if (value instanceof Boolean) {
cell.setCellValue((Boolean) value);
}else {
cell.setCellValue((String) value);
}
cell.setCellStyle(style);
}
outputStream.close();
}
}
2. Tambah dependency apache poi di pom.xml
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
document.open();
Font font = FontFactory.getFont(FontFactory.HELVETICA_BOLD);
font.setSize(18);
font.setColor(Color.BLUE);
document.add(p);
writeTableHeader(table, listColumn);
writeTableData(table, listUsers);
document.add(table);
document.close();
}
}
2. Tambah dependency openpdf di pom.xml
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.3.8</version>
</dependency>
}
PDF JasperReport
https://www.techgeeknext.com/spring-boot/spring-boot-jasper-report
1. Buat desain report dengan menggunakan jasper report studio
Untuk parameter data buat table pakai type data JBDataSourceCollection
2. Simpan file jrxml pada folder resource(src/main/resource)
3. Buat controller dan load file jrxml dan isi dengan data, kemudian generate pdf
@GetMapping("/jasper")
public void exportByJasper(HttpServletResponse response) {
try {
// create employee data
List<User> listUsers = (List<User>) userRepository.findAll();
ResourceUtils.getFile("classpath:jasperTemplate/employees-details.jrxml")
.getAbsolutePath()) // path of the jasper report
, empParams // dynamic parameters
, new JREmptyDataSource()
);
response.setContentType("application/pdf");
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
String currentDateTime = dateFormatter.format(new Date());
String headerKey = "Content-Disposition";
JasperExportManager.exportReportToPdfStream(empReport, response.getOutputStream());
} catch(Exception e) {
logger.error(e.toString());
}
}
Layouting
1. Buat folder fragments di folder resources/templates
2. Tambahkan code th:replace="fragments/header :: header"
Contoh:
Tampilan div akan diubah/direplace dengan code yang ada di file fragments/header.html
dengan id=”header”
https://www.bezkoder.com/spring-boot-jwt-authentication/ (use)
UPLOAD FILE
Referensi: https://www.bezkoder.com/spring-boot-file-upload/
https://www.baeldung.com/spring-boot-thymeleaf-image-upload