Showing posts with label spring boot. Show all posts
Showing posts with label spring boot. Show all posts

Sunday 5 September 2021

MapStruts

It's always tough for me to set the values for the POJO classes. If the POJO going to be complex it will kill my whole day. Hence I was googling and found some solutions to this can be seen here


In this post, we are going to see about the mapstruts.


What is Mapstruts?


MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach.


The generated mapping code uses plain method invocations and thus is fast, type-safe, and easy to understand.


hence by using Mapstruts not only simplifies our work of setting the POJO values also, removes the tight bonding between the code and mappings.


Also, this can be used in dto types, conversion of an object from one type to another where most of the properties remain same then we can use this mapstruts to achieve this.


The following steps are used for mapping.


Step:1 Maven dependency


<properties>

<java.version>1.8</java.version>

<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>

<m2e.apt.activation>jdt_apt</m2e.apt.activation>

</properties>


<dependency>

<groupId>org.mapstruct</groupId>

<artifactId>mapstruct</artifactId>

<version>${org.mapstruct.version}</version>

</dependency>


<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.8.1</version>

<configuration>

<source>1.8</source> <!-- depending on your project -->

<target>1.8</target> <!-- depending on your project -->

<annotationProcessorPaths>

<path>

<groupId>org.mapstruct</groupId>

<artifactId>mapstruct-processor</artifactId>

<version>${org.mapstruct.version}</version>

</path>

<!-- other annotation processors -->

</annotationProcessorPaths>

</configuration>

</plugin>

</plugins>

Step:2 Create Interface


package com.greet.user.mapper;


import org.mapstruct.DecoratedWith;

import org.mapstruct.Mapper;

import org.mapstruct.Mapping;

import org.mapstruct.Mappings;

import org.mapstruct.factory.Mappers;


import com.greet.user.GreetingPojo;

import com.greet.user.MessagePojo;

import com.greet.user.decorator.GreetDecorator;


@Mapper

@DecoratedWith(GreetDecorator.class)

public interface GreetMapper {


GreetMapper INSTANCE = Mappers.getMapper(GreetMapper.class);


@Mappings({ @Mapping(source = "message", target = "welcomeMessage"),

@Mapping(target = "greetings", constant = "I am From Mapstruts") })

GreetingPojo msgtoGreet(MessagePojo msgPojo);


}


@Mapper defines the mapper class, @Mappings used to map the values from the source object to target object. Then create a method msgtoGreet which converts  MessagePojo to GreetingPojo

object.


source are the properties from the MessagePojo and target is the properties from the GreetingPojo object.


Step:3 Create a decorator class


In case the objects need to make some changes we can use this decorator class to make those changes.


package com.greet.user.decorator;


import org.springframework.beans.factory.annotation.Autowired;


import com.greet.user.GreetingPojo;

import com.greet.user.MessagePojo;

import com.greet.user.mapper.GreetMapper;


public abstract class GreetDecorator implements GreetMapper {


@Autowired

private GreetMapper delegate;


public GreetDecorator(GreetMapper delegate) {

this.delegate = delegate;

}


@Override

public GreetingPojo msgtoGreet(MessagePojo msgPojo) {

GreetingPojo dto = delegate.msgtoGreet(msgPojo);

//add manipulations to the object here.

return dto;

}


}


Stpe:4 Invoking from the class.


call this where you have to convert the object.


GreetingPojo targetObj = GreetMapper.INSTANCE.msgtoGreet(msg);


This will convert the MessagePojo POJO to the GreetingPojo object.


Happy Learning!!!!


Saturday 10 July 2021

Generating the Pojo Classes automatically

There are scenarios, where we need to add the new attributes often, then the creation of POJO automatically will be helpful to you. You No need to make a lot of work, just do some changes it will create it. 

As far as I know, there are two ways we can generate these Pojo Classes.  

  • Using org.jvnet.jaxb2.maven2 
  • Using org.codehaus.mojo 

1. Generating through the org.jvnet.jaxb2.maven2 

The org.jvnet.jaxb2.maven2:maven-jaxb2-plugin, the most advanced and feature-full Maven plugin for XML Schema compilation. 


This Maven plugin wraps and enhances the JAXB Schema Compiler (XJC) and allows compiling XML Schemas (as well as WSDL, DTDs, RELAX NG) into Java classes in Maven builds. 


In order to use this, we need to have the XSD with us, through which we can generate the POJO classes. 


1.Create a directory in src/main/resources/XSD and copy the XSD file there. 

2.Add the Dependency there as like below. 

<plugin>

   <groupId>org.jvnet.jaxb2.maven2</groupId>

   <artifactId>maven-jaxb2-plugin</artifactId>

   <version>0.12.1</version>

   <executions>

      <execution>

         <id>generate</id>

         <goals>

            <goal>generate</goal>

         </goals>

      </execution>

   </executions>

   <configuration>

      <generatePackage>com.searchendeca.main.pojo</generatePackage>

      <generateDirectory>${project.basedir}/src/main/java</generateDirectory>

      <schemaDirectory>src/main/resources/xsd</schemaDirectory>

      <schemaIncludes>*.xsd</schemaIncludes>

   </configuration>

</plugin>

Here we need to specify where the files will be generated and the package it needs to generate then do alt+F5 which is Maven Refresh congratulations your POJO classes are generated automatically. 


2. Generating through the org.codehaus.mojo 

This plugin runs the XJC binding compiler from the JAXB distribution and integrates XJC’s configuration properties into a Maven project. 

Add the following dependency. 

<plugin>

   <groupId>org.codehaus.mojo</groupId>

   <artifactId>jaxb2-maven-plugin</artifactId>

   <version>2.4</version>

   <executions>

      <execution>

         <id>xjc</id>

         <goals>

            <goal>xjc</goal>

         </goals>

      </execution>

   </executions>

   <configuration>

      <sources>

         <source>src/main/resources/xsd/sample_CustomersOrders.xsd</source>

         <source>src/main/resources/xsd</source>

      </sources>

      <outputDirectory>src/main/java</outputDirectory>

      <!-- The package of your generated sources -->

      <packageName>com.searchendeca.main.pojo</packageName>

      <clearOutputDir>true</clearOutputDir>

      <addGeneratedAnnotation>false</addGeneratedAnnotation>

   </configuration>

</plugin>

 

If you are not specifying the output directory it will generate in the target folder. 

From the above two methods, I don’t see any difference apart from the groupId, it is to us which we can adopt for our project.  There are some tags different for specifying the output directory and package files etc. Again it's your call to adopt anyone, the second approach I see a lot of information on the internet.

Find the whole here.  

Happy Learning!!!!



 

Thursday 17 June 2021

Deploying SpringBoot Struts 2 Integration Project in Docker

 Follow my previous post and create the sample spring struts integration project from here.


Create a Docker File: Dockerfile


FROM tomcat:latest

ADD target/SpringStrutsDemo-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/

EXPOSE 8080

CMD ["catalina.sh","run"]


Build and tag the Docker File:spring-strutsdemo


C:\Users\Syed\Spring-workspace\SpringStrutsDemo>docker build -t spring-strutsdemo .

Sending build context to Docker daemon  58.75MB

Step 1/4 : FROM tomcat:latest

 ---> 5505f7218e4d

Step 2/4 : ADD target/SpringStrutsDemo-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/

 ---> a30a842ce761

Step 3/4 : EXPOSE 8080

 ---> Running in 35d616d2803f

Removing intermediate container 35d616d2803f

 ---> 2c848691227a

Step 4/4 : CMD ["catalina.sh","run"]

 ---> Running in 270c9c8d4b5d

Removing intermediate container 270c9c8d4b5d

 ---> f7b915b47c1f

Successfully built f7b915b47c1f

Successfully tagged spring-strutsdemo:latest


Run the docker image from the tag 


docker run -p 8080:8080 spring-strutsdemo

This will start in 8080 port. In case if it is not started well there could be an issue with the java version used in the docker or the project is not properly generated and war is invalid.

Access it using 

http://localhost:8080/SpringStrutsDemo-0.0.1-SNAPSHOT/message.action

where SpringStrutsDemo-0.0.1-SNAPSHOT is the context. 





Happy Learning!!!!



Spring Boot Struts 2 Integration

InOrder to Integrate Spring boot with the struts 2 follow the below Sample provided. This is a very basic project and gives you an understanding of the spring boot and Struts 2 Integration.

Create a Spring boot starter project with war packaging.


Maven Dependencies.


Add the Following dependencies to your maven project.

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>


<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-tomcat</artifactId>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>javax.servlet-api</artifactId>

</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api -->

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jsp-api</artifactId>

<version>2.0</version>

<scope>provided</scope>

</dependency>


<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>servlet-api</artifactId>

<version>2.5</version>

<scope>provided</scope>

</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->

<dependency>

<groupId>org.apache.struts</groupId>

<artifactId>struts2-core</artifactId>

<version>2.5.26</version>

</dependency>


<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin -->

<dependency>

<groupId>org.apache.struts</groupId>

<artifactId>struts2-spring-plugin</artifactId>

<version>2.5.26</version>

</dependency>


<dependency>

<groupId>org.apache.struts</groupId>

<artifactId>struts2-java8-support-plugin</artifactId>

<version>2.5.2</version>

</dependency>

</dependencies>


Create the Action Class: GreetUserAction.java


package com.searchendeca.demo.action;

import com.opensymphony.xwork2.ActionSupport;

public class GreetUserAction extends ActionSupport {

private String message;

    public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

@Override

    public String execute() throws Exception {

        return SUCCESS;

    }

}

This class should extend the ActionSupport class and has the default method as the execute.


Create Struts Configuration File: Struts2Configuration.java


package com.searchendeca.demo.config;


import org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;


import javax.servlet.DispatcherType;


@Configuration

public class Struts2Configuration {

    @Bean

    public FilterRegistrationBean someFilterRegistration() {

        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(new StrutsPrepareAndExecuteFilter());

        registration.addUrlPatterns("*.action");

        registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD);

        registration.setName("StrutsPrepareAndExecuteFilter");

        return registration;

    }

}


This is the place we filter the struts URL. In the above sample, we are allowing only URLs with the *.action.


Create Struts File: struts.xml


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>

    <constant name="struts.devMode" value="true"/>

    <package name="basicStruts2" extends="struts-default">

        <action name="message" class="com.searchendeca.demo.action.GreetUserAction" method="execute">

        <param name="message">Welcome to SearchEndeca</param>

            <result name="success">/greetUser.jsp</result>       

             </action>

    </package>

</struts>

In this File we register the action and map to the result. In the above example we are mapping the success result to the /greetUser. also sending the parameters message to display in the jsp.


Create Jsp:  greetUser.jsp


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

    "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Greet User</title>

</head>

<body>

    <center>

        <h3>${message}</h3>

    </center>

</body>

</html>


ServletInitializer Class: ServletInitializer.java


package com.searchendeca.demo;

import org.springframework.boot.builder.SpringApplicationBuilder;

import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(SpringStrutsDemoApplication.class);

}

}

SpringBoot Application Class :SpringStrutsDemoApplication.java

package com.searchendeca.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class SpringStrutsDemoApplication {


public static void main(String[] args) {

SpringApplication.run(SpringStrutsDemoApplication.class, args);

}

}


After this execute the command mvn : clean, package create the war file deploy it to either tomcat or the default server.


In-Browser Navigate to http://localhost:8080/SpringStrutsDemo/message.action





It Produces the above output.

This Project is available in Git here.

Happy Learning!!!!

Thursday 11 June 2020

Spring Boot With Docker

We have seen more definition about the containerization and its time for us to see some original work in action.
We will See in this post how to create a docker image and run from it. Of course, it is available in the spring site as a tutorial. I am providing here my version of achieving it.

The First you have to do with your application is to create the jar file of the application, this can be achieved by executing the below commands.

Prerequisite.

1.       If your application is maven based you have to execute the goal as” mvn:package”.

2.    Once you execute the package command it tries to create the jar and run the unit test cases, if you want not to execute the test cases then you can pass the following along with the goal. -Dmaven.test.skip=true

3.       Once the jar is generated you can check your application is running by calling the jar file.  Java -jar springbootdemo-0.0.1-SNAPSHOT.jar once you execute this, you can see the application started running.

4.       Download the docker from the website. https://docs.docker.com/installation/#installation and install it in the local. Makesure you are able to run the docker commands after installation.

Containerization.

1.       Create a file named “Dockerfile” with the following contents.

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

2   You can run the “docker build -t employeeservice . “ to create the tag.

This Dockerfile is very simple, but that’s all you need to run a Spring Boot app with no frills: just Java and a JAR file. The build will create a spring user and a spring group to run the application. It will then COPY the project JAR file into the container as "app.jar" that will be executed in the ENTRYPOINT. The array form of the Dockerfile ENTRYPOINT is used so that there is no shell wrapping the java process.

you can run the application using the following command.

docker run -p 7010:7010 employeeservice

That’s it now your application starts running from the docker image generated. Execute this from the directory where you have the docker file. On executing the build it will download the required and run the application locally.

That’s all Congrats on your first docker app.