"** Make a mockup like this quickly. ** ”Have you ever been given a task with such a sudden word?
When conducting failure investigations and feasibility studies, we sometimes create mockup applications that work with the application to be investigated, but the task we have discussed this time is also the creation of this mockup application.
I just want to create a mockup application that works with a small amount of effort, so this time I'll start by looking for a ** framework that I haven't used yet that seems to be quick to make.
First, I searched for the framework provided by OSS with ** GitHub ** with the search keyword java web framework microservice
. The search results are as follows.
Looking at the number of ★, ** tipsy / javalin ** is the first candidate, and ** pippo-java / pippo ** is the second candidate.
Next, check the features of the framework on the official website, and read the description on the site diagonally to see if it can meet the adoption conditions and functional requirements to be implemented.
Apparently, both of them meet the set conditions, so I was interested in "colorful and pop icons
andsize-conscious design (points that are supposed to be used in embedded devices)
, so this time Will try to adopt the second candidate ** Pippo **.
The core is small (around 140 KB) and we intend to keep it as small/simple as possible and to push new functionalities in pippo modules and third-party repositories/modules. You are not forced to use a specific template engine or an embedded web server. Furthermore you have multiple out of the box options (see Templates and Server). Also, Pippo comes with a very small footprint that makes it excellent for embedded devices (Raspberry Pi for example).
Immediately build a mockup application development environment.
Get the repository to your local environment from GitHub's Repository.
Follow the instructions in Quickstart, move to the root directory pippo
of the repository cloned to your local environment, and execute the following command.
Only the parts of -DgroupId
and -DartifactId
are changed.
mvn archetype:generate \
-DarchetypeGroupId=ro.pippo \
-DarchetypeArtifactId=pippo-quickstart \
-DarchetypeVersion=1.5.0 \
-DgroupId=com.example.mock \
-DartifactId=example-mock
You will be asked if you want to set the version of the module you built, so enter it here if you want to change it.
This time, the default 1.0-SNAPSHOT
is fine, so leave it empty and press the Enter key.
Define value for property 'version' 1.0-SNAPSHOT: :
Next, the settings will be confirmed, so if there are no problems, enter Y
.
[INFO] Using property: package = com.example.mock
Confirm properties configuration:
groupId: com.example.mock
artifactId: example-mock
version: 1.0-SNAPSHOT
package: com.example.mock
Y: :
A directory with the name ʻexample-mock specified by
-DartifactIdis created under the root directory
pippo`, so edit the following files to create a mockup application.
pippo
└─ example-mock
├─ pom.xml (Edit this file to add modules to use)
└─ src
└─ main
├─ java
│ └─ com
│ └─ example
│ └─ mock
│ ├─ PippoApplication.java (This time we will implement the process in this file)
│ └─ PippoLauncher.java
├─ resources
│ ├─ conf
│ │ ├─ application.properties
│ │ ├─ messages.properties
│ │ └─ messages_xx.properties etc (Messages according to locale.There are some properties)
│ ├─ templates
│ │ └─ hello.ftl
│ └─ simplelogger.properties (Logger settings edit this file)
└─ webapp
└─ WEB-INF
└─ web.xml
First, create a POJO that maps the request and response.
RequestParameter.java
package com.example.mock.common;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class RequestParameter implements Serializable {
private static final long serialVersionUID = 1L;
public String itemA;
public Boolean itemB;
}
ResponseParameter.java
package com.example.mock.common;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class ResponseParameter implements Serializable {
private static final long serialVersionUID = 1L;
//Response result (1:OK、0:NG)
public Integer result;
public String message;
}
Next, implement the logic to be executed when a JSON format request is accepted by POST.
PippoApplication.java
package com.example.mock;
import java.security.InvalidParameterException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.example.mock.common.RequestParameter;
import com.example.mock.common.ResponseParameter;
import ro.pippo.core.Application;
/**
* A simple Pippo application.
*
* @see com.example.mock.PippoLauncher#main(String[])
*/
public class PippoApplication extends Application {
private final static Logger log = LoggerFactory.getLogger(PippoApplication.class);
@Override
protected void onInit() {
getRouter().ignorePaths("/favicon.ico");
// send 'Hello World' as response
GET("/", routeContext -> routeContext.send("Hello World"));
//The part implemented this time is here
POST("/reqJson", routeContext -> {
log.debug("Check Request Parameters:" + routeContext.getRequest().getParameters());
log.debug("Check Request Body:" + routeContext.getRequest().getBody());
//Map the Body part of the request to the POJO for the request
RequestParameter reqParm = routeContext.createEntityFromBody(RequestParameter.class);
if (null == reqParm) {
throw new InvalidParameterException("Request Paramater is Invalid");
}
ResponseParameter resParm = new ResponseParameter();
//Judge the value of itemB of the request and switch the response
if (Boolean.FALSE == reqParm.itemB) {
// NG
resParm.result = Integer.valueOf(0);
resParm.message = "NG:" + reqParm.itemA;
log.debug("Check Result:NG");
} else {
// OK
resParm.result = Integer.valueOf(1);
resParm.message = "OK:" + reqParm.itemA;
log.debug("Check Result:OK");
}
//Return JSON format response
routeContext.json().send(resParm);
});
}
}
Edit simplelogger.properties
and modify it so that the log embedded this time is output.
Also, modify the log output date and time format so that the date is also output.
org.slf4j.simpleLogger.log.com.example.mock=debug
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss
Since the mock application created this time uses Jackson, add the following description to pom.xml
under the ʻexample-mock` directory.
pom.xml
<!-- Jackson -->
<dependency>
<groupId>ro.pippo</groupId>
<artifactId>pippo-jackson</artifactId>
<version>${pippo.version}</version>
</dependency>
Execute the command under the ʻexample-mock` directory.
mvn compile exec:java
Go to http: // localhost: 8338 /
with your browser and confirm that ** Hello World ** is displayed.
Send a JSON-formatted request with the cURL command and check the response result.
$ curl -H "Content-Type: application/json" -X POST "http://localhost:8338/reqJson" -d '{"itemA": "Test Request", "itemB": true}' -i
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 80 100 40 100 40 183 183 --:--:-- --:--:-- --:--:-- 197HTTP/1.1 200 OK
Date: Mon, 17 Dec 2018 02:53:48 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 40
Server: Jetty(9.4.6.v20170531)
{"result":1,"message":"OK:Test Request"}
Log output result
2018-12-17 11:53:48 [qtp188599000-16] DEBUG ro.pippo.core.PippoFilter - Request POST '/reqJson'
2018-12-17 11:53:48 [qtp188599000-16] DEBUG ro.pippo.core.route.DefaultRouter - Found 1 route matches for POST '/reqJson'
2018-12-17 11:53:48 [qtp188599000-16] DEBUG ro.pippo.core.route.DefaultRouteContext - Executing handler for POST '/reqJson'
2018-12-17 11:53:48 [qtp188599000-16] DEBUG com.example.mock.PippoApplication - Check Request Parameters:{}
2018-12-17 11:53:48 [qtp188599000-16] DEBUG com.example.mock.PippoApplication - Check Request Body:{"itemA": "Test Request", "itemB": true}
2018-12-17 11:53:48 [qtp188599000-16] DEBUG com.example.mock.PippoApplication - Check Result:OK
2018-12-17 11:53:48 [qtp188599000-16] DEBUG ro.pippo.core.route.RouteDispatcher - Returned status code 200 for POST '/reqJson'
$ curl -H "Content-Type: application/json" -X POST "http://localhost:8338/reqJson" -d '{"itemA": "Test Request", "itemB": false}' -i
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 81 100 40 100 41 182 187 --:--:-- --:--:-- --:--:-- 187HTTP/1.1 200 OK
Date: Mon, 17 Dec 2018 02:53:55 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 40
Server: Jetty(9.4.6.v20170531)
{"result":0,"message":"NG:Test Request"}
Log output result
2018-12-17 11:53:55 [qtp188599000-19] DEBUG ro.pippo.core.PippoFilter - Request POST '/reqJson'
2018-12-17 11:53:55 [qtp188599000-19] DEBUG ro.pippo.core.route.DefaultRouter - Found 1 route matches for POST '/reqJson'
2018-12-17 11:53:55 [qtp188599000-19] DEBUG ro.pippo.core.route.DefaultRouteContext - Executing handler for POST '/reqJson'
2018-12-17 11:53:55 [qtp188599000-19] DEBUG com.example.mock.PippoApplication - Check Request Parameters:{}
2018-12-17 11:53:55 [qtp188599000-19] DEBUG com.example.mock.PippoApplication - Check Request Body:{"itemA": "Test Request", "itemB": false}
2018-12-17 11:53:55 [qtp188599000-19] DEBUG com.example.mock.PippoApplication - Check Result:NG
2018-12-17 11:53:55 [qtp188599000-19] DEBUG ro.pippo.core.route.RouteDispatcher - Returned status code 200 for POST '/reqJson'
After the operation verification is completed, create ʻexample-mock / src / main / assembly / assembly.xml referring to the description in [Pippo site](http://www.pippo.ro/doc/deployment.html). I will. The contents of ʻassembly.xml
are as follows.
assembly.xml
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>app</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<scope>runtime</scope>
<outputDirectory>lib</outputDirectory>
<includes>
<include>*:jar:*</include>
</includes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>.</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
<excludes>
<exclude>*-javadoc.jar</exclude>
<exclude>*-sources.jar</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
This time, you don't need to edit pom.xml
because it follows the procedure of QuickStart. (Already mentioned when creating the mockup application template)
A build ʻexample-mock-1.0-SNAPSHOT.zip with the application server
Jettyis created in the
target` directory. The command to execute is as follows.
mvn clean package
If a separate application server such as Tomcat is prepared, execute the following command to build the War file of the mockup application.
mvn -Pwar package
Unzip the created Zip file ʻexample-mock-1.0-SNAPSHOT.zip` to an arbitrary directory, move to the unzipped directory, and then execute the following command.
java -jar example-mock-1.0-SNAPSHOT.jar
It was an impression that I made a mockup application using ** Pippo ** in a hurry, but I was able to confirm that the condition of ** making quickly ** was fully satisfied.
Set conditions | Evaluation |
---|---|
Must be a framework provided by OSS | ○ Apache 2.Provided with 0 license |
What can be implemented in Java | ○ |
Deploy from environment construction/Being able to do the work up to startup quickly | ○ The description of the document was easy to understand and I was able to do it quickly without clogging. |
Avoid consuming server resources as much as possible | ○ Both the size on the disk and the memory size used are small. |
The size of the web application I was looking forward to on disk was ** about 5.9MB **. (Including application server) For comparison, when I checked the size on the disk when deploying the War file to Tomcat (8.5.30: distribution is Core), it was ** about 14.5MB **. There was a difference of more than twice in the size on the disc, and I got the impression that it was quite small.
In addition, the heap size of the JVM can also be operated with the default value, and the memory usage confirmed by the task manager is ** about 61MB **, and the memory used is only considered for use in embedded devices. You can see the consideration for size.
For comparison, the memory usage when starting Tomcat and Jetty with the default settings was as follows.
I will also introduce the modularized Other Features if I have a chance.
Recommended Posts