Prática
Arquitetura Spring Boot

Construção do Projeto
Criar as funcionalidades
Execução

Ajustes no Controlador


Last updated




Last updated
[
{
"name": "Alice Santos",
"age": 28,
"position": "Marketing Analyst",
"department": "Marketing",
"city": "Rio de Janeiro",
"state": "RJ",
"workFormat": "On-site",
"salary": 4500
},
{
"name": "Bruno Oliveira",
"age": 32,
"position": "Backend Developer",
"department": "Technology",
"city": "São Paulo",
"state": "SP",
"workFormat": "Hybrid",
"salary": 7200
},
{
"name": "Carla Mendes",
"age": 41,
"position": "Project Manager",
"department": "Operations",
"city": "Curitiba",
"state": "PR",
"workFormat": "Remote",
"salary": 9800
},
{
"name": "Diego Ferreira",
"age": 25,
"position": "Support Intern",
"department": "IT",
"city": "Belo Horizonte",
"state": "MG",
"workFormat": "On-site",
"salary": 1800
},
{
"name": "Fernanda Costa",
"age": 29,
"position": "Financial Analyst",
"department": "Finance",
"city": "Porto Alegre",
"state": "RS",
"workFormat": "Hybrid",
"salary": 5200
},
{
"name": "Gustavo Lima",
"age": 37,
"position": "HR Coordinator",
"department": "Human Resources",
"city": "Salvador",
"state": "BA",
"workFormat": "On-site",
"salary": 6500
},
{
"name": "Juliana Rocha",
"age": 30,
"position": "Product Owner",
"department": "Products",
"city": "Recife",
"state": "PE",
"workFormat": "Remote",
"salary": 8700
},
{
"name": "Lucas Martins",
"age": 26,
"position": "UX/UI Designer",
"department": "Design",
"city": "Florianópolis",
"state": "SC",
"workFormat": "Hybrid",
"salary": 4800
},
{
"name": "Mariana Alves",
"age": 34,
"position": "Data Scientist",
"department": "Technology",
"city": "São Paulo",
"state": "SP",
"workFormat": "Remote",
"salary": 11500
},
{
"name": "Rodrigo Pires",
"age": 45,
"position": "Operations Director",
"department": "Executive Board",
"city": "Brasília",
"state": "DF",
"workFormat": "On-site",
"salary": 18000
}
]
netstat -ano | findstr :8080
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 22204
TCP [::]:8080 [::]:0 LISTENING 22204
taskkill /PID 22204 /Fnewfeatures
src/main/java
com.barbieri.newfeatures
NewFeaturesApplication.java
com.barbieri.newfeatures.controller
EmployeeControle.java
com.barbieri.newfeatures.entity
Employee.java
com.barbieri.newfeatures.repository
EmployeeRepository.java
com.barbieri.newfeatures.service
EmployeeService.java
EmployeeServiceImpl.javapackage com.barbieri.newfeatures.entity;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="employee")
public class Employee {
private String name;
private int age;
private String position;
private String department;
private String city;
private String state;
private String workFormat;
private double salary;
}package com.barbieri.newfeatures.entity;
import java.util.Objects;
public class Employee {
private String name;
private int age;
private String position;
private String department;
private String city;
private String state;
private String workFormat;
private double salary;
public Employee(String name, int age, String position, String department, String city, String state,
String workFormat, double salary) {
super();
this.name = name;
this.age = age;
this.position = position;
this.department = department;
this.city = city;
this.state = state;
this.workFormat = workFormat;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getWorkFormat() {
return workFormat;
}
public void setWorkFormat(String workFormat) {
this.workFormat = workFormat;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + ", position=" + position + ", department=" + department
+ ", city=" + city + ", state=" + state + ", workFormat=" + workFormat + ", salary=" + salary
+ ", getName()=" + getName() + ", getAge()=" + getAge() + ", getPosition()=" + getPosition()
+ ", getDepartment()=" + getDepartment() + ", getCity()=" + getCity() + ", getState()=" + getState()
+ ", getWorkFormat()=" + getWorkFormat() + ", getSalary()=" + getSalary() + ", getClass()=" + getClass()
+ ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
}
@Override
public int hashCode() {
return Objects.hash(age, city, department, name, position, salary, state, workFormat);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
return age == other.age && Objects.equals(city, other.city) && Objects.equals(department, other.department)
&& Objects.equals(name, other.name) && Objects.equals(position, other.position)
&& Double.doubleToLongBits(salary) == Double.doubleToLongBits(other.salary)
&& Objects.equals(state, other.state) && Objects.equals(workFormat, other.workFormat);
}
}package com.barbieri.newfeatures.service;
import java.util.List;
import com.barbieri.newfeatures.entity.Employee;
public interface EmployeeService {
List<Employee> listAll();
}
package com.barbieri.newfeatures.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.barbieri.newfeatures.entity.Employee;
import com.barbieri.newfeatures.repository.EmployeeRepository;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
@Override
public List<Employee> listAll() {
List<Employee> employees = new ArrayList<>();
employeeRepository.findAll().forEach(employees::add);
return employees;
}
}
package com.barbieri.newfeatures.controller;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
}package com.barbieri.newfeatures.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import com.barbieri.newfeatures.service.EmployeeService;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
}
package com.barbieri.newfeatures.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.barbieri.newfeatures.entity.Employee;
import com.barbieri.newfeatures.service.EmployeeService;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/listEmployees")
public ResponseEntity<List<Employee>> listEmployees()
{
List<Employee> employees = employeeService.listAll();
return new ResponseEntity<List<Employee>>(employees,HttpStatus.OK);
}
}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.5.5)
2025-09-01T18:00:18.412-03:00 INFO 29552 --- [newfeatures] [ main] c.b.newfeatures.NewfeaturesApplication : Starting NewfeaturesApplication using Java 21.0.8 with PID 29552 (C:\Users\mpbarbieri.TOPAZ.000\Downloads\newfeatures\target\classes started by mpbarbieri in C:\Users\mpbarbieri.TOPAZ.000\Downloads\newfeatures)
2025-09-01T18:00:18.414-03:00 INFO 29552 --- [newfeatures] [ main] c.b.newfeatures.NewfeaturesApplication : No active profile set, falling back to 1 default profile: "default"
2025-09-01T18:00:18.948-03:00 INFO 29552 --- [newfeatures] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
2025-09-01T18:00:19.004-03:00 INFO 29552 --- [newfeatures] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 48 ms. Found 1 MongoDB repository interface.
2025-09-01T18:00:19.348-03:00 INFO 29552 --- [newfeatures] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2025-09-01T18:00:19.362-03:00 INFO 29552 --- [newfeatures] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-09-01T18:00:19.363-03:00 INFO 29552 --- [newfeatures] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.44]
2025-09-01T18:00:19.405-03:00 INFO 29552 --- [newfeatures] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2025-09-01T18:00:19.406-03:00 INFO 29552 --- [newfeatures] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 954 ms
2025-09-01T18:00:19.591-03:00 INFO 29552 --- [newfeatures] [ main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 10", "architecture": "amd64", "version": "10.0"}, "platform": "Java/Eclipse Adoptium/21.0.8+9-LTS"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@5afbd567, com.mongodb.Jep395RecordCodecProvider@6993c8df, com.mongodb.KotlinCodecProvider@57545c3f]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
2025-09-01T18:00:19.624-03:00 INFO 29552 --- [newfeatures] [localhost:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, cryptd=false, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=25, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=18181500, minRoundTripTimeNanos=0}
2025-09-01T18:00:20.094-03:00 INFO 29552 --- [newfeatures] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2025-09-01T18:00:20.102-03:00 INFO 29552 --- [newfeatures] [ main] c.b.newfeatures.NewfeaturesApplication : Started NewfeaturesApplication in 2.051 seconds (process running for 2.311)
package com.barbieri.newfeatures.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.barbieri.newfeatures.entity.Employee;
import com.barbieri.newfeatures.service.EmployeeService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/")
public ResponseEntity<String> start()
{
// region "response html"...
String response = """
<!doctype html>
<html lang="pt-br" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title th:text="${appName} + ' | Início'">Início</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;margin:0;padding:0;background:#f6f7f9;color:#222}
header{background:#0f172a;color:#fff;padding:16px 24px}
main{max-width:960px;margin:24px auto;padding:0 16px}
.card{background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:20px;box-shadow:0 1px 2px rgba(0,0,0,.05)}
.actions a, .actions button{display:inline-block;margin-right:8px;padding:10px 14px;border-radius:10px;border:1px solid #e5e7eb;background:#fff;cursor:pointer;text-decoration:none;color:#111}
.actions a:hover, .actions button:hover{background:#f1f5f9}
footer{text-align:center;color:#6b7280;margin:32px 0;font-size:14px}
</style>
</head>
<body>
<header>
<h1 th:text="${appName}">NewFeatures</h1>
</header>
<main>
<section class="card">
<h2>Página Inicial</h2>
<p>Bem-vindo. Escolha uma ação.</p>
<div class="actions">
<a href="/listEmployees">Listar Funcionários</a>
</div>
</section>
</main>
<footer>
© <span th:text="${#dates.year(#dates.createNow())}">2025</span> - NewFeatures
</footer>
</body>
</html>
""";
// endregion
return new ResponseEntity<String>(response,HttpStatus.OK);
}
@GetMapping("/listEmployees")
public ResponseEntity<List<Employee>> listEmployees()
{
List<Employee> employees = employeeService.listAll();
return new ResponseEntity<List<Employee>>(employees,HttpStatus.OK);
}
}