Moving From the Full-stack JS World to the Java Galaxy ⚡⚡

Rebai Ahmed
7 min readOct 25, 2020

Hi in this blog I will write about my experience as a Full-stack developer with Java technology as I mentioned in the title “The Java Galaxy “, I will present my different steps of evolution of my small knowledge about this cool technology.

My Beginning 🚲 :

My Beginning
  • When I was a student and while learning to program I got advice form a coach to learn the JS frameworks and tools like Nodejs, Angularjs, He said “Don’t Follow the JEE stack, the JS Avenger will take the whole development world and it will be the trend number one
  • So my experience started with Angularjs/Express, moving after to Angular 2, React native (Thanks to Anouar who advises me to switch to RN), JWT, Token Authentication, Cross-platform mobile development,(I still remember my old days and my passion for programming )

My Steps With Java (Spring boot framework)

Spring Boot

While the first professional experience I was recruited as Js Developer should have the required skills (React, Redux, GraphQL, Nodejs, etc ), But after some time I heard the project was leaved

so I need to adapt as a Spring/Angular Developer with the main stack of the enterprise

In my beginning, I was always scared from trying with the spring boot and the Java world, while seeing our teammates’ seniors code and knowledge about it I feel like nothing

Learning RoadMap 🚗:

I just set a Roadmap to learn and practice some spring boot tips and tricks, I’m so thankful for my colleagues Wali, Bilel, Khaled, And Amir who are always advising me about the best resources to learn from, tips that I should do in my free time

Top Ressources to follow :

Things learned until Now :

So after more than one year of experience with Java development, I feel like I learned a lot of things and always still needed to learn!

Spring boot Annotations ✂️ 📐:

— REST API — :

@RestController : To make simply a Rest Controller in spring (specialized version of @Controller in Spruing MVC)@RequestMapping("/users"): to map the HTTP Requests to the concerned controller (for our example to handle all the api requests to /users
@GetMapping("/all") : to map only the HTTP GET requests@PostMapping : to map only the HTTP POSTrequests@RequestMapping(value = "/yourUrl", method = RequestMethod.POST):Another method to define your HTTP requests handler , you can specify the method POST | GET | PUT | DELETE etc..@PathVariable : used to pass params via URI , example /users/{userId}@RequestBody: maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization@RequestParam(value = "paramName", required = false): to inject params with your HTTP requests for example GET API with filter
yourUrlAPi?paramName=__value__
@ControllerAdvice: allows to handle exceptions across the whole application in one global handling component

— Service Layer — :

@Service : annotation is used with classes that provide some business functionalities

— Repository — :

@Repository :  is a Spring annotation that indicates that the decorated class is a repository

— Config — :

Class : HandlerInterceptor : 
* preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
* postHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
* afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler) :
Example class to add an interceptor to your spring boot application to catch the requets and it's provide methods to follow teh requets lifecycle
@Value("${spring.application.urlApi}") : annotation is used to assign default values to variables and method arguments, fro example from your application.properties to your classes attributes

— Data models — :


@Document : to define your class as a document to be stored in your Mongodb Database (thanks to Spring data )
@Id :applied at the field level to mark the field used for identiy purpose.@NotBlank(groups = ModelCreation.class,message = "fieldName.notSetted")@NotNull(groups = ModelCreation.class,message = "fieldName.notSetted") :
Are used for to some some constraints validations
@DBREF : Annotation used to define the concerned fiedl as reference to another document

Mapstruct:

Mapstrcut is a java library which provides us the automatic mapping between two java Beans, the most use cases are “Entity To DTO Conversion”, all that you have to do is to define an interface that extends EntityMapper

public interface EntityNameMapper extends EntityMapper<ModelDTO, Model>

Auditing Entity 🔍 🔎 :

A generic class to keep track of who created or changed an entity and the point in time this happened.

public abstract class AbstractAuditingEntity implements Serializable {

private static final long serialVersionUID = 1L;

@CreatedBy
private User createdBy;

@CreatedDate
private Instant createdDate = Instant.now();


@LastModifiedBy
private User lastModifiedBy;


@LastModifiedDate
private Instant lastModifiedDate = Instant.now();

The Design Patterns ⚒ 🛠 ⛏:

  • The Builder pattern :

The Builder pattern is a creational pattern used to created and initialize objects that solve the problem of Too many constructor arguments and Incorrect object state.

public class yourClass{

private String field;



public String getField() {
return field;
}

public yourCla field(String field) {
this.field= field;
return this;
}

Recommended Project structure 📓 📕 📗 📘 📙 📔 :

  • web/rest: for your REST API controllers layer
  • service: your business logic layer
  • repository: the data access object layer
  • domain: your entities layer
  • dto: define your DTO classes
  • config: your configuration (cors config, swagger config, database config, Thymeleaf Config, etc.)
  • security: your security layer will handle the authorisation ad the authentification layer

JAVA 8 Features practiced ✏️ :

The Optional : class which is supposed to cure NullPointerExceptions.

that offers many advantages like :

  • No more NullPointer Exceptions
  • Null checks are not required
  • No more Boilerplate code
String[] str = new String[10];     
Optional<String> isNull = Optional.ofNullable(str[9]);
if(isNull.isPresent()){
//Getting the substring
String str2 = str[9].substring(2, 5);
//Displaying substring
System.out.print("Substring is: "+ str2);
}
else{
System.out.println("Cannot get the substring from an empty string");
}

Stream API : Stream is a new abstract layer introduced in Java 8. Using stream, you can process data in a declarative way similar to SQL statements. For example, consider the following SQL statement.

Example Map operation:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

//get list of unique squares
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

Cools things are done with Spring Boot ✌️ :

Scheduled Tasks :

I have implemented a task which requires a scheduled job and persisting data, i really like it, how to handle exceptions, during job execution and how to confirm that your job is correctly done

@Scheduled(cron = "0 * 9 * * ?")
public void cronJobSch() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date now = new Date();
String strDate = sdf.format(now);
logger.info("Java cron job expression:: {}" ,strDate);
}

Custom Annotations :

Another cool thing I liked is the Custom annotation implementation,

the use cases were for Enum Type validation and

- make a custom annotation for the APIS audit (to track each post and update HTTP query with simple annotation in the controller Layer “@EventCaptor”)

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ValueOfEnumValidator.class)
public @interface ValueOfEnum {
Class<? extends Enum<?>> enumClass();

String message() default "must be any of enum {enumClass}";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}
-------------------------------------------------------------------------------------------------------------------------------
"Second Use Case"
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface EventCaptor {

ActionType actionType();
}
@PostMapping
@EventCaptor(actionType = ActionType.CREATION)
@ApiOperation(value = "Create a new instance")
public ResponseEntity<ProductDTO> createProduct( @RequestBody @Valid ProductDTO classDTO, Principal principal)
throws URISyntaxException {
final classDTO result = classService.createExample(classDTO);
return ResponseEntity.created(new URI("/api/class/")
}

Aspect-oriented programming :

@Aspect
@Component
public class YourClassAspect {
@AfterReturning(value = "execution(* com.softilys.soyouz.web.rest..*(..))", returning = "retVal")
public void auditEventPointcut(JoinPoint pjp, ResponseEntity retVal) {
EventCaptor myAnnotation =
((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(EventCaptor.class);
String[] argNames = ((MethodSignature) pjp.getSignature()).getParameterNames();
String productId = "";
if (myAnnotation != null
&& checkReturnedValueIsNotEmptyResponseEntity(retVal)
&& (myAnnotation.actionType().equals(ActionType.CREATION)
|| myAnnotation.actionType().equals(ActionType.UPDATE))) {
//---------your action------------//
}
}

Custom Mongodb Queries:

With “mongoOperations” provide for us how to define custom queries like mongodb queries whil solves many problems for us

Example of implementation:

final Query query = new Query();
query.addCriteria(Criteria.where("criteriaOne").is(productID));
query.with(Sort.by(Sort.Direction.ASC, "createdDate"));
return mongoOperations.find(query, YourClas.class);

Code Refactoring ⛏ :

I’m currently learning the Java By Comparison book and it’s really a very interesting book for those who want to learn how to improve their code quality and learn best practices of it, things captured until now

Variables && Functions Naming conventions

Avoid unnecessary comparison

Avoid negations

Simplify your Boolean Expressions

DRY: Don’t Repeat yourself

Favor For each Over For loops

Format Over Concatenation (Strings)

Enums Over Integer Constants

Conclusion ✍️:

In conclusion, I just created a repository in GitHub called learning-spring-boot to try and practise the spring boot modules different tips and tricks and to growth more

Happy Reading 🙂

--

--