BAEL-20884 Move Spring Boot Rest to Spring Boot Modules
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
## Core Java Modules
|
||||
|
||||
This module contains modules about Sprint Boot
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.spring-boot-modules</groupId>
|
||||
<artifactId>spring-boot-modules</artifactId>
|
||||
<name>spring-boot-modules</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>spring-boot-rest</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,28 @@
|
||||
## Spring Boot REST
|
||||
|
||||
This module contains articles about Spring Boot RESTful APIs.
|
||||
|
||||
### Relevant Articles
|
||||
|
||||
- [HATEOAS for a Spring REST Service](https://www.baeldung.com/rest-api-discoverability-with-spring)
|
||||
- [Versioning a REST API](https://www.baeldung.com/rest-versioning)
|
||||
- [ETags for REST with Spring](https://www.baeldung.com/etags-for-rest-with-spring)
|
||||
- [Testing REST with multiple MIME types](https://www.baeldung.com/testing-rest-api-with-multiple-media-types)
|
||||
- [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections)
|
||||
- [Spring Boot Consuming and Producing JSON](https://www.baeldung.com/spring-boot-json)
|
||||
- [Error Handling for REST with Spring](https://www.baeldung.com/exception-handling-for-rest-with-spring)
|
||||
|
||||
### E-book
|
||||
|
||||
These articles are part of the Spring REST E-book:
|
||||
|
||||
1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
|
||||
2. [Build a REST API with Spring and Java Config](https://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration)
|
||||
3. [Http Message Converters with the Spring Framework](https://www.baeldung.com/spring-httpmessageconverter-rest)
|
||||
4. [Spring’s RequestBody and ResponseBody Annotations](https://www.baeldung.com/spring-request-response-body)
|
||||
5. [Entity To DTO Conversion for a Spring REST API](https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application)
|
||||
6. [Error Handling for REST with Spring](https://www.baeldung.com/exception-handling-for-rest-with-spring)
|
||||
7. [REST API Discoverability and HATEOAS](https://www.baeldung.com/restful-web-service-discoverability)
|
||||
8. [An Intro to Spring HATEOAS](https://www.baeldung.com/spring-hateoas-tutorial)
|
||||
9. [REST Pagination in Spring](https://www.baeldung.com/rest-api-pagination-in-spring)
|
||||
10. [Test a REST API with Java](https://www.baeldung.com/integration-testing-a-rest-api)
|
||||
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.web</groupId>
|
||||
<artifactId>spring-boot-rest</artifactId>
|
||||
<name>spring-boot-rest</name>
|
||||
<packaging>war</packaging>
|
||||
<description>Spring Boot Rest Module</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
</dependency>
|
||||
<!-- We'll need to comment out the jackson-dataformat-xml dependency if we want to use XStream: -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-oxm</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>${xstream.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring HATEOAS -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- util -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.modelmapper</groupId>
|
||||
<artifactId>modelmapper</artifactId>
|
||||
<version>${modelmapper.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<start-class>com.baeldung.SpringBootRestApplication</start-class>
|
||||
<guava.version>27.0.1-jre</guava.version>
|
||||
<xstream.version>1.4.11.1</xstream.version>
|
||||
<modelmapper.version>2.3.5</modelmapper.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBootRestApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootRestApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ModelMapper modelMapper() {
|
||||
return new ModelMapper();
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.persistence;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface IOperations<T extends Serializable> {
|
||||
|
||||
// read - one
|
||||
|
||||
T findById(final long id);
|
||||
|
||||
// read - all
|
||||
|
||||
List<T> findAll();
|
||||
|
||||
Page<T> findPaginated(int page, int size);
|
||||
|
||||
// write
|
||||
|
||||
T create(final T entity);
|
||||
|
||||
T update(final T entity);
|
||||
|
||||
void delete(final T entity);
|
||||
|
||||
void deleteById(final long entityId);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.persistence.dao;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
|
||||
public interface IFooDao extends JpaRepository<Foo, Long> {
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.baeldung.persistence.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class Customer extends ResourceSupport {
|
||||
private String customerId;
|
||||
private String customerName;
|
||||
private String companyName;
|
||||
private Map<String, Order> orders;
|
||||
|
||||
public Customer() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Customer(final String customerId, final String customerName, final String companyName) {
|
||||
super();
|
||||
this.customerId = customerId;
|
||||
this.customerName = customerName;
|
||||
this.companyName = companyName;
|
||||
}
|
||||
|
||||
public String getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(final String customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(final String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
public String getCompanyName() {
|
||||
return companyName;
|
||||
}
|
||||
|
||||
public void setCompanyName(final String companyName) {
|
||||
this.companyName = companyName;
|
||||
}
|
||||
|
||||
public Map<String, Order> getOrders() {
|
||||
return orders;
|
||||
}
|
||||
|
||||
public void setOrders(final Map<String, Order> orders) {
|
||||
this.orders = orders;
|
||||
}
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.baeldung.persistence.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
@XStreamAlias("Foo")
|
||||
@Entity
|
||||
public class Foo implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
public Foo() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Foo(final String name) {
|
||||
super();
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final Foo other = (Foo) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("Foo [name=").append(name).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.baeldung.persistence.model;
|
||||
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
public class Order extends ResourceSupport {
|
||||
private String orderId;
|
||||
private double price;
|
||||
private int quantity;
|
||||
|
||||
public Order() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Order(final String orderId, final double price, final int quantity) {
|
||||
super();
|
||||
this.orderId = orderId;
|
||||
this.price = price;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(final String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(final double price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(final int quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order [orderId=" + orderId + ", price=" + price + ", quantity=" + quantity + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.persistence.service;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import com.baeldung.persistence.IOperations;
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
|
||||
public interface IFooService extends IOperations<Foo> {
|
||||
|
||||
Page<Foo> findPaginated(Pageable pageable);
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.baeldung.persistence.service.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.persistence.IOperations;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@Transactional
|
||||
public abstract class AbstractService<T extends Serializable> implements IOperations<T> {
|
||||
|
||||
// read - one
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public T findById(final long id) {
|
||||
return getDao().findById(id).orElse(null);
|
||||
}
|
||||
|
||||
// read - all
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> findAll() {
|
||||
return Lists.newArrayList(getDao().findAll());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<T> findPaginated(final int page, final int size) {
|
||||
return getDao().findAll(PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
// write
|
||||
|
||||
@Override
|
||||
public T create(final T entity) {
|
||||
return getDao().save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T update(final T entity) {
|
||||
return getDao().save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(final T entity) {
|
||||
getDao().delete(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(final long entityId) {
|
||||
getDao().deleteById(entityId);
|
||||
}
|
||||
|
||||
protected abstract PagingAndSortingRepository<T, Long> getDao();
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.persistence.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baeldung.persistence.dao.IFooDao;
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.baeldung.persistence.service.IFooService;
|
||||
import com.baeldung.persistence.service.common.AbstractService;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class FooService extends AbstractService<Foo> implements IFooService {
|
||||
|
||||
@Autowired
|
||||
private IFooDao dao;
|
||||
|
||||
public FooService() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
protected PagingAndSortingRepository<Foo, Long> getDao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
// custom methods
|
||||
|
||||
@Override
|
||||
public Page<Foo> findPaginated(Pageable pageable) {
|
||||
return dao.findAll(pageable);
|
||||
}
|
||||
|
||||
// overridden to be secured
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<Foo> findAll() {
|
||||
return Lists.newArrayList(getDao().findAll());
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.requestresponsebody;
|
||||
|
||||
import com.baeldung.services.ExampleService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/post")
|
||||
public class ExamplePostController {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(ExamplePostController.class);
|
||||
|
||||
@Autowired ExampleService exampleService;
|
||||
|
||||
@PostMapping("/request")
|
||||
public ResponseEntity postController(@RequestBody LoginForm loginForm) {
|
||||
log.debug("POST received - serializing LoginForm: " + loginForm.getPassword() + " " + loginForm.getUsername());
|
||||
exampleService.fakeAuthenticate(loginForm);
|
||||
return ResponseEntity.ok(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/response")
|
||||
@ResponseBody
|
||||
public ResponseTransfer postResponseController(@RequestBody LoginForm loginForm) {
|
||||
log.debug("POST received - serializing LoginForm: " + loginForm.getPassword() + " " + loginForm.getUsername());
|
||||
return new ResponseTransfer("Thanks For Posting!!!");
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.requestresponsebody;
|
||||
|
||||
public class LoginForm {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public LoginForm() {
|
||||
}
|
||||
|
||||
public LoginForm(String username, String password) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.requestresponsebody;
|
||||
|
||||
public class ResponseTransfer {
|
||||
|
||||
private String text;
|
||||
|
||||
public ResponseTransfer(String text) {
|
||||
this.setText(text);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.services;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.persistence.model.Customer;
|
||||
|
||||
public interface CustomerService {
|
||||
|
||||
List<Customer> allCustomers();
|
||||
|
||||
Customer getCustomerDetail(final String id);
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.services;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.persistence.model.Customer;
|
||||
|
||||
@Service
|
||||
public class CustomerServiceImpl implements CustomerService {
|
||||
|
||||
private HashMap<String, Customer> customerMap;
|
||||
|
||||
public CustomerServiceImpl() {
|
||||
|
||||
customerMap = new HashMap<>();
|
||||
|
||||
final Customer customerOne = new Customer("10A", "Jane", "ABC Company");
|
||||
final Customer customerTwo = new Customer("20B", "Bob", "XYZ Company");
|
||||
final Customer customerThree = new Customer("30C", "Tim", "CKV Company");
|
||||
|
||||
customerMap.put("10A", customerOne);
|
||||
customerMap.put("20B", customerTwo);
|
||||
customerMap.put("30C", customerThree);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Customer> allCustomers() {
|
||||
return new ArrayList<>(customerMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Customer getCustomerDetail(final String customerId) {
|
||||
return customerMap.get(customerId);
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.services;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.requestresponsebody.LoginForm;
|
||||
|
||||
@Service
|
||||
public class ExampleService {
|
||||
|
||||
public boolean fakeAuthenticate(LoginForm lf) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.services;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.persistence.model.Order;
|
||||
|
||||
public interface OrderService {
|
||||
|
||||
List<Order> getAllOrdersForCustomer(String customerId);
|
||||
|
||||
Order getOrderByIdForCustomer(String customerId, String orderId);
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.baeldung.services;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.persistence.model.Customer;
|
||||
import com.baeldung.persistence.model.Order;
|
||||
|
||||
@Service
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
|
||||
private HashMap<String, Customer> customerMap;
|
||||
private HashMap<String, Order> customerOneOrderMap;
|
||||
private HashMap<String, Order> customerTwoOrderMap;
|
||||
private HashMap<String, Order> customerThreeOrderMap;
|
||||
|
||||
public OrderServiceImpl() {
|
||||
|
||||
customerMap = new HashMap<>();
|
||||
customerOneOrderMap = new HashMap<>();
|
||||
customerTwoOrderMap = new HashMap<>();
|
||||
customerThreeOrderMap = new HashMap<>();
|
||||
|
||||
customerOneOrderMap.put("001A", new Order("001A", 150.00, 25));
|
||||
customerOneOrderMap.put("002A", new Order("002A", 250.00, 15));
|
||||
|
||||
customerTwoOrderMap.put("002B", new Order("002B", 550.00, 325));
|
||||
customerTwoOrderMap.put("002B", new Order("002B", 450.00, 525));
|
||||
|
||||
final Customer customerOne = new Customer("10A", "Jane", "ABC Company");
|
||||
final Customer customerTwo = new Customer("20B", "Bob", "XYZ Company");
|
||||
final Customer customerThree = new Customer("30C", "Tim", "CKV Company");
|
||||
|
||||
customerOne.setOrders(customerOneOrderMap);
|
||||
customerTwo.setOrders(customerTwoOrderMap);
|
||||
customerThree.setOrders(customerThreeOrderMap);
|
||||
customerMap.put("10A", customerOne);
|
||||
customerMap.put("20B", customerTwo);
|
||||
customerMap.put("30C", customerThree);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Order> getAllOrdersForCustomer(final String customerId) {
|
||||
return new ArrayList<>(customerMap.get(customerId).getOrders().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order getOrderByIdForCustomer(final String customerId, final String orderId) {
|
||||
final Map<String, Order> orders = customerMap.get(customerId).getOrders();
|
||||
Order selectedOrder = orders.get(orderId);
|
||||
return selectedOrder;
|
||||
}
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
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 com.google.common.base.Preconditions;
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@PropertySource({ "classpath:persistence-${envTarget:h2}.properties" })
|
||||
@ComponentScan(basePackages = { "com.baeldung.persistence", "com.baeldung.springpagination" })
|
||||
@EnableJpaRepositories(basePackages = {"com.baeldung.persistence.dao", "com.baeldung.springpagination.repository"})
|
||||
public class PersistenceConfig {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
public PersistenceConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||
em.setDataSource(dataSource());
|
||||
em.setPackagesToScan(new String[] { "com.baeldung.persistence.model", "com.baeldung.springpagination.model" });
|
||||
|
||||
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
// vendorAdapter.set
|
||||
em.setJpaVendorAdapter(vendorAdapter);
|
||||
em.setJpaProperties(additionalProperties());
|
||||
|
||||
return em;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
|
||||
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
|
||||
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
|
||||
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
|
||||
|
||||
return transactionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
|
||||
return new PersistenceExceptionTranslationPostProcessor();
|
||||
}
|
||||
|
||||
final Properties additionalProperties() {
|
||||
final Properties hibernateProperties = new Properties();
|
||||
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
|
||||
return hibernateProperties;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
|
||||
import org.springframework.oxm.xstream.XStreamMarshaller;
|
||||
import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
// If we want to enable xml configurations for message-converter:
|
||||
// @ImportResource("classpath:WEB-INF/api-servlet.xml")
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
// @Override
|
||||
// public void configureMessageConverters(final List<HttpMessageConverter<?>> messageConverters) {
|
||||
// messageConverters.add(new MappingJackson2HttpMessageConverter());
|
||||
// messageConverters.add(createXmlHttpMessageConverter());
|
||||
// }
|
||||
//
|
||||
// private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
|
||||
// final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
|
||||
//
|
||||
// final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
|
||||
// xstreamMarshaller.setAutodetectAnnotations(true);
|
||||
// xmlConverter.setMarshaller(xstreamMarshaller);
|
||||
// xmlConverter.setUnmarshaller(xstreamMarshaller);
|
||||
//
|
||||
// return xmlConverter;
|
||||
// }
|
||||
|
||||
// Another possibility is to create a bean which will be automatically added to the Spring Boot Autoconfigurations
|
||||
// @Bean
|
||||
// public HttpMessageConverter<Object> createXmlHttpMessageConverter() {
|
||||
// final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
|
||||
//
|
||||
// final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
|
||||
// xstreamMarshaller.setAutodetectAnnotations(true);
|
||||
// xmlConverter.setMarshaller(xstreamMarshaller);
|
||||
// xmlConverter.setUnmarshaller(xstreamMarshaller);
|
||||
//
|
||||
// return xmlConverter;
|
||||
// }
|
||||
|
||||
// Etags
|
||||
|
||||
// If we're not using Spring Boot we can make use of
|
||||
// AbstractAnnotationConfigDispatcherServletInitializer#getServletFilters
|
||||
@Bean
|
||||
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
|
||||
FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<>( new ShallowEtagHeaderFilter());
|
||||
filterRegistrationBean.addUrlPatterns("/foos/*");
|
||||
filterRegistrationBean.setName("etagFilter");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
|
||||
// We can also just declare the filter directly
|
||||
// @Bean
|
||||
// public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
|
||||
// return new ShallowEtagHeaderFilter();
|
||||
// }
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.baeldung.springpagination.controller;
|
||||
|
||||
import com.baeldung.springpagination.dto.PostDto;
|
||||
import com.baeldung.springpagination.model.Post;
|
||||
import com.baeldung.springpagination.service.IPostService;
|
||||
import com.baeldung.springpagination.service.IUserService;
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
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.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/posts")
|
||||
public class PostRestController {
|
||||
|
||||
@Autowired
|
||||
private IPostService postService;
|
||||
|
||||
@Autowired
|
||||
private IUserService userService;
|
||||
|
||||
@Autowired
|
||||
private ModelMapper modelMapper;
|
||||
|
||||
@GetMapping
|
||||
@ResponseBody
|
||||
public List<PostDto> getPosts(
|
||||
@PathVariable("page") int page,
|
||||
@PathVariable("size") int size,
|
||||
@PathVariable("sortDir") String sortDir,
|
||||
@PathVariable("sort") String sort) {
|
||||
|
||||
List<Post> posts = postService.getPostsList(page, size, sortDir, sort);
|
||||
return posts.stream()
|
||||
.map(this::convertToDto)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@ResponseBody
|
||||
public PostDto createPost(@RequestBody PostDto postDto) throws ParseException {
|
||||
Post post = convertToEntity(postDto);
|
||||
Post postCreated = postService.createPost(post);
|
||||
return convertToDto(postCreated);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{id}")
|
||||
@ResponseBody
|
||||
public PostDto getPost(@PathVariable("id") Long id) {
|
||||
return convertToDto(postService.getPostById(id));
|
||||
}
|
||||
|
||||
@PutMapping(value = "/{id}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public void updatePost(@RequestBody PostDto postDto) throws ParseException {
|
||||
Post post = convertToEntity(postDto);
|
||||
postService.updatePost(post);
|
||||
}
|
||||
|
||||
|
||||
private PostDto convertToDto(Post post) {
|
||||
PostDto postDto = modelMapper.map(post, PostDto.class);
|
||||
postDto.setSubmissionDate(post.getSubmissionDate(),
|
||||
userService.getCurrentUser().getPreference().getTimezone());
|
||||
return postDto;
|
||||
}
|
||||
|
||||
private Post convertToEntity(PostDto postDto) throws ParseException {
|
||||
Post post = modelMapper.map(postDto, Post.class);
|
||||
post.setSubmissionDate(postDto.getSubmissionDateConverted(
|
||||
userService.getCurrentUser().getPreference().getTimezone()));
|
||||
|
||||
if (postDto.getId() != null) {
|
||||
Post oldPost = postService.getPostById(postDto.getId());
|
||||
post.setRedditID(oldPost.getRedditID());
|
||||
post.setSent(oldPost.isSent());
|
||||
}
|
||||
return post;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.baeldung.springpagination.dto;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class PostDto {
|
||||
|
||||
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
private Long id;
|
||||
|
||||
private String title;
|
||||
|
||||
private String url;
|
||||
|
||||
private String date;
|
||||
|
||||
private UserDto user;
|
||||
|
||||
public Date getSubmissionDateConverted(String timezone) throws ParseException {
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone(timezone));
|
||||
return dateFormat.parse(this.date);
|
||||
}
|
||||
|
||||
public void setSubmissionDate(Date date, String timezone) {
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone(timezone));
|
||||
this.date = dateFormat.format(date);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public UserDto getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserDto user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.springpagination.dto;
|
||||
|
||||
public class UserDto {
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.baeldung.springpagination.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Post {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String title;
|
||||
|
||||
private String url;
|
||||
|
||||
private String date;
|
||||
|
||||
private String redditID;
|
||||
|
||||
private Date submissionDate;
|
||||
|
||||
private boolean sent;
|
||||
|
||||
private String userName;
|
||||
|
||||
public Post() {
|
||||
|
||||
}
|
||||
|
||||
public boolean isSent() {
|
||||
return sent;
|
||||
}
|
||||
|
||||
public void setSent(boolean sent) {
|
||||
this.sent = sent;
|
||||
}
|
||||
|
||||
public String getRedditID() {
|
||||
return redditID;
|
||||
}
|
||||
|
||||
public void setRedditID(String redditID) {
|
||||
this.redditID = redditID;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public Date getSubmissionDate() {
|
||||
return submissionDate;
|
||||
}
|
||||
|
||||
public void setSubmissionDate(Date submissionDate) {
|
||||
this.submissionDate = submissionDate;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.springpagination.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Preference {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String timezone;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.springpagination.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Subject {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
public Subject() {
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.springpagination.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToOne
|
||||
Preference preference;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Preference getPreference() {
|
||||
return preference;
|
||||
}
|
||||
|
||||
public void setPreference(Preference preference) {
|
||||
this.preference = preference;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user