Boilerplate components for Spring Boot.
- E-mail sending with step builder
- Request logging
- Files uploading to Amazon S3
- Response wrapping (works with Swagger / SpringFox!)
- Easy to use CORS filter
<dependency>
  <groupId>com.jpomykala</groupId>
  <artifactId>spring-higher-order-components</artifactId>
  <version>1.0.11</version>
</dependency>Check version in maven repository
- Write inline code
- Duplicate code a few times in different spots
- Extract duplicate code into methods
- Use your abstractions for a while
- See how that code interacts with other code
- Extract common functionality into internal library
- Use internal library for extended periods of time
- Really understand how all of the pieces come together
- Create external open source library (we are here now)
source: https://nickjanetakis.com
This component gives you simple API to send emails using Amazon SES service. Spring HOC will automatically create for you Amazon SES component if bean doesn't exist.
- Provide verified sender email address spring-hoc.mail.sender-email-address
- Provide AWS credentials spring-hoc.aws.access-key,spring-hoc.aws.secret-key,spring-hoc.aws.region
spring-hoc:
  aws:
    access-key: xxxxxxxx
    secret-key: xxxxxxxx
    region: eu-west-1
  mail:
    sender-email-address: "[email protected]"    This properties are required.
You can put My Company Name <[email protected]> in sender-email-address property to show "My Company Name" in e-mail apps instead plain e-mail.
Reference: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-concepts-email-format.html
Use EmailRequest step builder to create request.
EmailRequest.builder()
            .to("[email protected]")
            .subject("Hey, I just met you and this is crazy")
            .body("But here's my number, so call me maybe")
            .build();Now it's time to send email. You have 2 options here.
- @Autowire MailServiceand invoke- sendEmail(EmailRequest).
- Publish EmailRequestusingApplicationEventPublisher
That's all!
@SpringBootApplication
@EnableEmailSending
public class MySpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MySpringBootApplication.class, args);
  }
  // Send e-mail by event publishing, Spring HOC will listen to EmailRequest objects 
  @Autowired
  private ApplicationEventPublisher eventPublisher;
  @GetMapping("/send-email-by-event-publishing")
  public void sendEmailByEventPublishing(){
    EmailRequest emailRequest = EmailRequest.builder()
            .to("[email protected]")
            .subject("Hey, I just met you and this is crazy [event publishing]")
            .body("But here's my number, so call me maybe")
            .build();
    eventPublisher.publishEvent(emailRequest);
  }
  
  // Send e-mail by mail service provided by Spring HOC and @EnableEmailSending annotation
  @Autowired
  private MailService mailService;
  @GetMapping("/send-email-by-mail-service")
  public void sendEmailByMailService(){
    EmailRequest emailRequest = EmailRequest.builder()
            .to("[email protected]")
            .subject("Hey, I just met you and this is crazy [mail service]")
            .body("But here's my number, so call me maybe")
            .build();
    mailService.send(emailRequest);
  }
}Adds logging requests, populate MDC with:
- user (IP address by default)
- requestId (UUID by default).
@SpringBootApplication
@EnableRequestLogging
public class MySpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MySpringBootApplication.class, args);
  }
  @Autowired
  private MyUserService userService;
  // [OPTIONAL] customize configuration
  @Bean
  public LoggingFilter loggingFilter(LoggingFilterFactory loggingFilterFactory) {
    return loggingFilterFactory
            .withPrincipalProvider(new PrincipalProvider() {
              @Override
              public String getPrincipal(HttpServletRequest request) {
                return userService.findUserName(request);
              }
            })
            .createFilter();
  }
}@Bean
public LoggingFilter loggingFilter(LoggingFilterFactory loggingFilterFactory){
  return loggingFilterFactory
          .withPrincipalProvider() // [optional] PrincipalProvider implementation 
          .withRequestIdProvider() // [optional] RequestIdProvider implementation
          .withCustomMdc("user", "[u:%s][rid:%s]") // [optional] MDC key, String.format()
          .createFilter();
}This annotation autoconfigures Amazon S3 component if bean doesn't exit.
@Autowire UploadService gives you ability to upload files using overloaded methods:
- void upload(@NotNull UploadRequest uploadRequest)
- void upload(@NotNull MultipartFile file)
- void upload(@NotNull MultipartFile file, @NotNull String path)
- void upload(byte[] bytes, String fileKey)
- void upload(byte[] bytes, String fileKey, ObjectMetadata metadata)
- String upload(byte[] bytes)// path is autogenerated (sha256 hash)
spring-hoc:
  aws:
    access-key: xxxxxxxx
    secret-key: xxxxxxxx
    region: eu-west-1
  s3:
    bucket-name: my-bucket
This properties are required.*
@SpringBootApplication
@EnableFileUploading
public class MySpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MySpringBootApplication.class, args);
  }
  @Autowired
  private UploadService uploadService;
  @GetMapping("/upload-file")
  public String uploadFile(@RequestBody MultipartFile multipartFile) throws IOException {
    String s3DownloadUrl = uploadService.upload(multipartFile);
    return s3DownloadUrl;
  }
}Every @RestController output will be wrapped into RestResponse<T> object for JSON it will look like as follows:
{
  msg: "OK"
  status: 200
  data: <your data>
  pageDetails: <page details if you return Page from controller>
}
RestResponse static contructors:
- RestResponse ok(Object body)
- RestResponse ok(Object body, PageDetails pageDetails)
- RestResponse empty(String message, HttpStatus status)
- RestResponse of(String message, HttpStatus status, Object data)
- RestResponse of(String message, HttpStatus status, Object data, PageDetails pageDetails)
Every output will be wrapped into RestResponse see this issue
Response wrapping can be disabled for specific endpoinds by using @DisableWrapping annotation on method.
@SpringBootApplication
@EnableResponseWrapping
public class MySpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MySpringBootApplication.class, args);
  }
  @GetMapping("/wrap-pojo")
  public MyPojo wrapResponse() {
    MySpringBootApplication.MyPojo myPojo = new MyPojo("Jakub", "Pomykala");
    return myPojo;
  }
  
  @Autowired
  private MyPojoRepository myPojoRepository;
  @GetMapping("/wrap-pojo-page")
  public Page<MyPojo> wrapPageResponse() {
    Page<MyPojo> myPojos = myPojoRepository.findAll();
    return myPojos;
  }
  
  public class MyPojo {
    private String firstName;
    private String lastName;
    // getters and setters
  }
}This annotation adds filter which handles CORS requests.
spring-hoc:
  cors:
    allow-credentials: true
    allowed-origins:
      - "https://my-frontend-application.com"
      - "https://jpomykala.com"
    allowed-methods:
      - GET
      - POST
      - PATCH
      - DELETEThis properties are optional.
By default CORS will accept all origins, all HTTP methods and all popular headers.
@SpringBootApplication
@EnableCORS
public class MySpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MySpringBootApplication.class, args);
  }
}Would you like to add something or improve source? Create new issue, let's discuss it
- If in doubt, please discuss your ideas first before providing a pull request. This often helps avoid a lot of unnecessary work. In particular, we might prefer not to prioritise a particular feature for another while.
- Fork the repository.
- The commit message should reference the issue number.
- Check out and work on your own fork.
- Try to make your commits as atomic as possible. Related changes to three files should be committed in one commit.
- Try not to modify anything unrelated.
Source: https://github.com/jOOQ/jOOQ
- Check out my website
GNU General Public License v3.0
