Showing posts with label JAVA. Show all posts
Showing posts with label JAVA. Show all posts

Sunday 5 September 2021

XML and Json Response Format using Jackson

There will be some scenarios, where you need to send both the XML and JSON output based on the calling client requests. This might become sometimes tricky if we are using the Message Converters other than Jackson provides the ability to generate both the XML and JSON. 


Follow the below steps:


Step:1 Maven dependency.


<dependency>

<groupId>com.fasterxml.jackson.dataformat</groupId>

<artifactId>jackson-dataformat-xml</artifactId>

<version>2.10.0</version>

</dependency>


Add the above dependency, once this is available the message convertor Jackson will be available.


Stpe:2 Define the outputs in the Controller.


@RestController

public class HelloController {

@RequestMapping(value = "/greet", consumes = MediaType.APPLICATION_JSON_VALUE, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })

public GreetingPojo index() {

MessagePojo msg = new MessagePojo();

msg.setMessage("Greetings from Spring Boot!");

// GreetingPojo targetObj = new DozerBeanMapper().map(msg, GreetingPojo.class);

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

return targetObj;

}

}


Stpe:3 Request for Json/Xml



We need to update the Accept Header to get the application/xml or application/Json. It will generate the output accordingly.


The only Constraint is we need to pass the object from the controller as it. The Jackson takes everything.

Happy Learning !!!!


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!!!!


Sunday 18 July 2021

Object Mappers in Java

What is the mean by object mapper? 


As the name suggests mapping the data from one object to another? Consider the situation where you want to convert the object from one form to another. If the Object is simpler, then we can iterate and save it in the new object where else in case of the complex objects it is tougher to save it, because you need to iterate all the objects and save it. Which will add more adhoc. In order to overcome this, we have the Object mapper APIs.


There are various Object Mapper APIs are available, which we can see in the individual posts. Some are


1. Dozer.

2. MapStruts

3. ModelMapper 

4. Apache Bean Utils.


Using these API we can convert from one object to another with minimal effort.

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!!!!



 

Monday 5 July 2021

Create Xml Using the Stax Processor

StAX is a standard XML processing API that allows you to stream XML data from and to your application.


This API is better than the DOM parser in the case of Performance. It does not load the whole document to the memory like the DOM parser. SAX is a push API where else Stax is the pull API. Using the SAX for the creation of the document is not recommended.


The Below code is used to generate the below XML.



package com.searchendeca.main;

import java.io.StringWriter;


import javax.xml.stream.XMLOutputFactory;

import javax.xml.stream.XMLStreamException;

import javax.xml.stream.XMLStreamWriter;


public class StaxParserMain {


private void createStudentElements(XMLStreamWriter xmlStreamWriter) {

try {

createStreamWriter("FirstName", "Syed", xmlStreamWriter);

createStreamWriter("LastName", "Ghouse", xmlStreamWriter);

createStreamWriter("City", "Salem", xmlStreamWriter);

} catch (XMLStreamException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

private void createStreamWriter(String key, Object value, XMLStreamWriter xmlStreamWriter)

throws XMLStreamException {

if (value != null && value != "") {

if (value instanceof String) {

xmlStreamWriter.writeStartElement(key);

xmlStreamWriter.writeCharacters((String) value);

xmlStreamWriter.writeEndElement();

}

} else {

xmlStreamWriter.writeEmptyElement(key);

}


}


public static void main(String args[]) {

StringWriter stringwriter = new StringWriter();

XMLOutputFactory xmloutputfactory = XMLOutputFactory.newInstance();

StaxParserMain stax = new StaxParserMain();

try {

XMLStreamWriter xmlStreamWriter = xmloutputfactory.createXMLStreamWriter(stringwriter);

xmlStreamWriter.writeStartDocument();

xmlStreamWriter.writeStartElement("Student");

stax.createStudentElements(xmlStreamWriter);

xmlStreamWriter.writeEndElement();

xmlStreamWriter.writeEndDocument();

xmlStreamWriter.flush();

xmlStreamWriter.close();

String xmlString= stringwriter.getBuffer().toString();

System.out.println(xmlString);


} catch (XMLStreamException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}


}


The whole project can be found in Github here.


Happy Learning !!!

Create XML Using DOM Parser in JAVA

The Document Object Model (DOM) is an official recommendation of the World Wide Web Consortium (W3C). DOM reads the entire document and will be useful in case of the size of the XML is small. Performance-wise this is slow compared to other parsers since it loads the entire document. We can Perform the Operations using the DOM API.Its Stays in Tree Structure.


We can construct the Following XML using the DOM Parser.



We need to understand the following to get started.

The Node interface is the primary datatype for the entire Document Object Model. It represents a single node in the document tree. 

The Element interface represents an element in an HTML or XML document. Elements may have attributes associated with them; since the Element interface inherits from Node, the generic Node interface attribute attributes may be used to retrieve the set of all attributes for an element. 

In order to use the dom parser include the following dependency in the maven.

 <dependency>

   <groupId>xml-apis</groupId>

   <artifactId>xml-apis</artifactId>

   <version>1.4.01</version>

</dependency>


In the case of the Spring boot project, this should be included as part of the starter package itself I guess.


package com.searchendeca.main;

import java.io.StringWriter;


import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.OutputKeys;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;


import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;


public class DomParserMain {


private Element createStudentElement(Document doc, Element rootElement) {

rootElement.appendChild(createElements(doc, "FirstName", "Syed"));

rootElement.appendChild(createElements(doc, "LastName", "Ghouse"));

rootElement.appendChild(createElements(doc, "City", "Salem"));

return rootElement;

}


private Node createElements(Document doc, String name, String value) {

Element node = doc.createElement(name);

if (value != null && !value.isEmpty()) {

node.appendChild((doc.createTextNode(value)));

}

return node;

}


public static void main(String args[]) throws ParserConfigurationException {


DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

DocumentBuilder dBuilder;

String sampleXml;

DomParserMain domParser = new DomParserMain();

dBuilder = dbFactory.newDocumentBuilder();

Document doc = dBuilder.newDocument();

Element rootElement = doc.createElement("Student");

doc.appendChild(rootElement);

rootElement = domParser.createStudentElement(doc, rootElement);

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = null;

try {

transformer = factory.newTransformer();

StringWriter writer = new StringWriter();

try {

transformer.setOutputProperty(OutputKeys.INDENT, "yes");

transformer.transform(new DOMSource(doc), new StreamResult(writer));

sampleXml = writer.getBuffer().toString();

System.out.println(sampleXml);

} catch (TransformerException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

} catch (TransformerConfigurationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}


}



The above code creates the XML in the desired output.


The Whole Project can be found in the Github link here.


Happy Learning!!!!!