Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

JMiddleWay for Web Applications

DZone's Guide to

JMiddleWay for Web Applications

Learn how to use this open-source Java framework to assist in the set up of the APIs you need to develop your next web application.

· Web Dev Zone ·
Free Resource

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

The Why

My intention is to provide a middleware framework which can be used to add REST APIs without worrying about involving several technologies and their various versions.  The user can define the architecture with JMiddleWay as the middleman between its UI and back-end services. You can choose the UI and back-end technologies of your choice and add the necessary code to JMiddleWay to integrate with your architecture.

The What

The best way to get to know the technology is to build a prototype with it. And that’s exactly what I did and what I will present in this post. JMiddleWay lets you create your own middleware quickly and add the required REST APIs easily. You can plug in your authentication module and configure how and where your middleware should log. Though fairly simple, the example highlights the most common annotations you’ll need to build your own REST API.

The main focus in the post will be on the Jersey JAX-RS implementation, all the other technologies are viewed as enablers.

Technologies Used

  • Spring 4.0.3
  • Jersey 2.8
  • Log4j 1.1.1
  • Maven 3.1
  • Tomcat 8

Follow Along

You can find all you'll need on GitHub.

Project Dependencies

Among other things, you need to have the Jersey Spring extension in your project’s classpath. You can easily add that with Maven by adding the following dependencies to the pom.xml file of the project:

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <version>${jersey.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.2.3</version>
</dependency>

Note: Jersey uses its own version of Spring libraries, so to use the ones you want, you need to exclude these libraries manually.

Code alert: If you want to see what other dependencies are used in the project you can download the complete pom.xml file from GitHub.

Web Application Deployment Descriptor – web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>JMiddleWay</display-name>
  <listener>
      <listener-class>
          org.springframework.web.context.ContextLoaderListener
      </listener-class>
  </listener>
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <servlet>
      <servlet-name>JMiddleWay - Middlwawre framework</servlet-name>
      <servlet-class>
          org.glassfish.jersey.servlet.ServletContainer
      </servlet-class>
      <init-param>
          <param-name>javax.ws.rs.Application</param-name>
          <param-value>com.jmiddleway.app.JMiddleWayApp_JAXRS_app</param-value>
      </init-param>
      <init-param>
          <param-name>javax.ws.rs.container.ContainerRequestFilters</param-name>
          <param-value>com.jmiddleway.log.JMiddleWayLoggingFilter</param-value>
      </init-param>
      <init-param>
          <param-name>javax.ws.rs.container.container.ContainerResponseFilters</param-name>
          <param-value>com.jmiddleway.log.JMiddleWayLoggingFilter</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>JMiddleWay - Middlwawre framework</servlet-name>
      <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

Jersey-servlet

Notice the Jersey servlet configuration, the javax.ws.rs.application class, defines the components of the JAX-RS application.

Package com.jmiddleway.app:

/*

 * Author  : Aravinda

 * Description :JAX RX Application class, Registers the components to be used by the JAX-RS application

 * Company :  

 */
import java.util.logging.Logger;
import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.bridge.SLF4JBridgeHandler;
import com.jmiddleway.app.ExceptionMappers.JMiddleWayExceptionMapper;
import com.jmiddleway.app.ExceptionMappers.JMiddleWayGenericExceptionMapper;
import com.jmiddleway.app.filters.ApplicationContextProvider;
import com.jmiddleway.log.JMiddleWayLoggingFilter;
import com.jmiddleway.log.LoggerInjector;

public class JMiddleWayApp_JAXRS_app extends ResourceConfig {

   public JMiddleWayApp_JAXRS_app() {

      packages("com.jmiddleway");
      register(LoggerInjector.class);
      register(JMiddleWayExceptionMapper.class);
      register(JMiddleWayGenericExceptionMapper.class);
      register(ApplicationContextProvider.class);
  // Optionally remove existing handlers attached to j.u.l root logger
      SLF4JBridgeHandler.removeHandlersForRootLogger();  // (since SLF4J 1.6.5)

      // add SLF4JBridgeHandler to j.u.l's root logger, should be done once during
  // the initialization phase of your application

      SLF4JBridgeHandler.install();
      registerInstances(new JMiddleWayLoggingFilter(Logger.getLogger(JMiddleWayApp_JAXRS_app.class.getName()), true));            
   }
}

The class registers the following components:

  • JMiddleWayExceptionMapper implements the generic interface ExceptionMapper from the javax.ws.rs.ext package. This helps in generating uniform exception returning to the client if JMiddleWay or the back-end generates an exception defined by JMiddleWayException.
  • JMiddleWayGenericExceptionMapper implements the generic interface ExceptionMapper from the javax.ws.rs.ext package. This helps in generating uniform exception returning to the client if JMiddleWay or the back-end generates an exception other than JMiddleWayException.
  • ApplicationContextProvider - This class provides application-wide access to the Spring ApplicationContext! The ApplicationContext is injected in a static method of the class, "AppContext."

Spring Application Context Configuration

The Spring application context configuration is located in the applicationContext.xml classpath. 

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:util="http://www.springframework.org/schema/util"
  xmlns:task="http://www.springframework.org/schema/task"

  xsi:schemaLocation="http://www.springframework.org/schema/beans      
                      http://www.springframework.org/schema/beans/spring-beans.xsd                          http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx.xsd
      http://www.springframework.org/schema/task
  http://www.springframework.org/schema/task/spring-task-4.0.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd">
  <context:annotation-config />
  <task:annotation-driven />
  <context:component-scan base-package="com.jmiddleway.*" />
  <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"

           proxy-target-class="false"  />
  <!--  JMiddleWayServletContext - provides a servelet context to help in autowire beans -->
  <bean id="jMiddleWayServletContext" class="com.jmiddleway.util.JMiddleWayServletContext"></bean>
  <!--  LoggerInjector - helps to inject Logger to any bean -->
  <bean class="com.jmiddleway.log.LoggerInjector" />
  <!--  Add your beans -->
</beans>

REST APIs

Sample API:

@Component

@Path("/YourResource")

public class YourResource {
   @Autowired
   private YourResourceService yourResourceService;

   @GET
   @Produces("application/json")
   public Response GetYourResource(@Context HttpServletRequest request) throws JMiddleWayException {        
return yourResourceService.getYourResource(request);
   }

   @POST    
   @Consumes("application/json")
   @Produces("application/json")
   public Response CreateYourResource(@Context HttpServletRequest request) throws JMiddleWayException {
return yourResourceService.createYourResource(request);
   }

   @PUT
   @Consumes("application/json")
   @Produces("application/json")
   public Response UpdateYourResource(@Context HttpServletRequest request) throws JMiddleWayException {
return yourResourceService.updateYourResource(request);
   }

   @DELETE
   @Consumes("application/json")
   @Produces("application/json")
   public Response DeleteYourResource(@Context HttpServletRequest request) throws JMiddleWayException {
return yourResourceService.deleteYourResource(request);
   }
}

How to Use JMiddleWay

  • Create a new Dynamic web project using Eclipse.
    • Give your Project a name, such as JMiddleWay, and link to the location of the Git repository - - https://github.com/aravindatanneer/jmiddleway
    • Select the Target runtime for ex-Apache Tomcat 8.0.
    • Select Generate web.xml deployment descriptor.
    • Finish.
    • Right-click on the project and select configure to convert it to a Maven project – pom.xml is created.
    • Update the pom.xml and web.xml as mentioned above.
    • Add your rest APIs – copy the class, YourResource, and modify it according to your requirements.
    • Export the war file to the web app directory in Tomcat if your runtime is Tomcat.
    • See the logback.properties file in the classpath and change the location of the logfile. Currently, it is /tmp and the name of the file will be jmiddleway followed by the date. Also, check the logback.xml for the configuration of the logfile.
    • Test APIs using any REST client – I prefer the Chrome REST client.

If you have an authentication mechanism built-in to JMiddleWay, then write the test client by calling an API with the appropriate authentication mechanism.

What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

Topics:
java rest api ,web dev ,xml

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}