Saturday, 14 October 2017

Three ways solving Spring Boot Cannot determine embedded database driver class for database type NONE

If you don’t have a DataSource configured for your spring boot application, when you run spring boot application, it tries to configure the DataSource and throws this error message when there is no configuration provided.

We have three ways to slove this:

1) If you don't need any data source, just exclude it as below:


@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class SpringBootDemoApplication { }
2) If you need ds just for test purpose, say using an embedded DB like HSqldb, just add the dependency in your pom or yml file:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>


3) Or you want to have your own external DB configuration, you need to provided DS information in spring boot configuration file, generally add below into application.properties is fine:
spring.datasource.url=xxx
spring.datasource.* is the default prefix for spring boot data source configuration, if you use other prefix, you may need add your own ds configuration file.

Wednesday, 4 October 2017

access-control-allow-origin

When do development, especially front end and back end are separated in different projects, it is easy to get  access-control-allow-origin error when call webservices.

For this, we have some solutions:

1) For front end, we can add some proxy logic to redirect front end HTTP request through proxy, for instance, our front end application runs on http://localhost:3000, and back end application on http://localhost:8000, if front end make a service call to back end, say /api/v1/students, the call will proxyed to http://localhost:8000/api/v1/students, not http://localhost:3000/api/v1/students, thus avoiding access-control-allow-origin error from the browser. for instance, if you use gulp serve, in server.js file, you can use 'http-proxy-middleware':

var proxyMiddleware = require('http-proxy-middleware');
server.middleware = proxyMiddleware('/api', {target: 'http://localhost:8888', changeOrigin: true});

For 'http-proxy-middleware' can get more info in: https://github.com/chimurai/http-proxy-middleware

2) Otherwise, we can add some logic on back end, e.g. if we use spring framework,  we can use @CrossOrigin annotation on method, class or global level. For global enabled we can add this annotation in one of the configuration classes is OK:
@Configuration @CrossOrigin public class WebConfig { }

3) Or we can just do something without code, say if we use Chrome, we can add the plugin


This will also avoid this error.

Saturday, 30 September 2017

HTML 5 form validation not work with onclick

form validation is the form been validated before submit. So if you want to use HTML 5 default form validation with the submit button which has an onclick event, the form validation will not work as it is skipped, because these validations are performed when the form is submitted, in fact the button with onclick method just call a normal js function.

In order to make the default validation rule take effect, some issues should be considered:

1) for the submit button, we can use either:
<button type="submit">Submit</button>
or
<input type="submit" value="Submit">
the key point here is we should have the attribute inside: type="submit"

2) instead of using onclick, we should use onsubmit in the <form>, for instance:
<form onsubmit="aFunction()">...</form>
and then the aFunction() should be invoked when the form validation passed.

How to do the validation inside our own js function, HTML5 introduces a concept called "constraint validation" which is an algorithm browsers run when a form is submitted to determine its validity. To make this determination, the algorithm utilizes new HTML5 attributes like min, max, step, pattern, and required as well as existing attributes maxlength and type.

Another choise is validate the form using DOM API:

validity is a DOM property that will returns a validityState object which contains several boolean properties for us to use, say we have a node:
var ele = document.getElementById('someId');
Example
Validity property
Notes
<input id="someId" pattern="[0-9]{4}" value="123" />
ele.validity.patternMismatch
true if the node's value does not match its pattern attribute
<input id="someId" type="number" max="2" value="1" />
ele.validity.rangeOverflow
true if the node's value is greater than its max attribute
<input id="someId" type="number" min="2" value="3" />
ele.validity.rangeUnderflow
true if the node's value is less than its min attribute
 <input id="someId" type="email" value="abc" />
ele.validity.typeMismatch
true if an input node's value is invalid per its type attribute
<input id="someId" type="text" required value=" " />
ele.validity.valueMissing
true if the node has a required attribute but has no value
<input id="someId" type="text" required value="" />
ele.validity.valid
true if all of the validity conditions listed above are false

checkValidity()

The checkValidity method on a form element node (e.g. input, select, textarea) returns true if the element contains valid data, for instance:

if(ele.checkValidity()){
...
}


On form nodes it returns true if all of the form's children contain valid data,i.e.
if(document.forms['aForm'].checkValidity()){
        ...
}

In fact we do not need <form> but only a <div></div> to accommodate all the input controls, and using a <button onclick="aFun(...params)"></button>, the validation rule can be performed as below:

    if(document.getElementById("firstName").validity.valueMissing){
        alert('firstName is required');
        return false;
    }else{
        user.firstName = document.getElementById("firstName").value;
    }

Tuesday, 19 September 2017

Eclipse Speed Up

Cleaning up history and indexes reduce the load on RAM, and overall HDD usage as well. This result in very high impact on performance. To remove the indexes and history folders, please cleanup all files/folders inside these two folders:
For cleaning up indexes
{workspace path}\.metadata\.plugins\org.eclipse.jdt.core
For cleaning up history
{workspace path}\.metadata\.plugins\org.eclipse.core.resources\.history
Here {workspace path} is the path of eclipse workspace where you create all projects.

Sunday, 27 August 2017

Java Web Service SOAP REST


Simple introduction of JAX-WS and JAX-RS, with code, implementation, SOAP request and response, and comparison.

See Java Web Service

Monday, 25 January 2016

Three approachs to solve JSON recursive dependency (circular dependency) Stackoverflow

Using Jackson to serialize my JPA entities with many-to-many relationship into JSON, I got a wrong JSON response and the application entered in an infinite loop giving as output an infinite recursion Stackoverflow error.

To solve the problem, there are general two ways according to the Jackson documentation.

Approach 1
Before Jackson 2.0, handling of cyclic object graphs was limited to specific case of parent/child(bi-directional) references. Using @JsonManagedReference and @JsonBackReference

Add the @JsonManagedReference in the forward part of the relationship which you want to serialize, and add in the back part of the relationship which will not be serialized. See the following example that Material and Supplier is @ManyToMany relationship.

@Entity
public class Material{
    ...
    @JsonManagedReference 
    private List<Supplier> costSuppliers = new ArrayList<>();
    ...
}
   
@Entity
public class Supplier{
    ...
    @JsonBackReference
    private List<Material> costMaterials = new ArrayList<>();
    ....
}
If we serialize a Material instance to JSON, we will get an Array containing Supplier instances, but the drawback of this approach is that, when we serialize a Supplier instance to JSON, we will not get the Material array instance.

Approach 2
Jackson 2 provides a new annotation @JsonIdentityInfo which is used for indicating that values of annotated type or property should be serializing so that instances either contain additional object identifier, or as a reference that consists of an object id that refers to a full serialization. For the last example will be someting like this:
@Entity
public class Material{
    ...
    private List<Supplier> costSuppliers = new ArrayList<>();
    ...
}
   
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class Supplier{
    ...
    private List<Material> costMaterials = new ArrayList<>();
    ....
}

Thus the cyclic dependency and Stackoverflow issue could be solved. But the drawback is that, just as the Jackson documentation says:
"In practice this is done by serializing the first instance as full object and object identity, and other references to the object as reference values."
It means that, say, we serialized a Material object which has an Supplier array, however, only the first  element of the array is Supplier object, the rest elements in the array is not Supplier object but Supplier reference (general the id). This not what a want, cause generally I want to render the whole properties of the Supplier object, but I need to request the Supplier info again with its reference :(

Approach 3
Forget @JsonManagedReference, @JsonBackReference, and @JsonIdentityInfo, we just use the simple  @JsonIgnoreProperties, see below:

@Entity
public class Material{
    ...   
  @JsonIgnoreProperties("costMaterials")
    private List<Supplier> costSuppliers = new ArrayList<>();
    ...
}
   
@Entity
public class Supplier{
    ...
  @JsonIgnoreProperties("costSuppliers")
    private List<Material> costMaterials = new ArrayList<>();
    ....
}

Simple annotation and simple use, NO infinite recursive Stackoverflow and get all the "Object" information in the serialized JSON :)


Tuesday, 12 January 2016

REST API for create-form and update-form resource

Generally, when comes to create a resource using REST, the URI is something looks like:
POST /orders
so how to represent a create and edit forms urls?

According to RFC 6861, we can use create-form and edit-form links to discover the url, say:
{
    ...
    "_links" : {
        "self" : {
            "href" : "/orders/1"
        },
        "createform" : {
            "rel" : "create-form",
            "href" : "/orders/createform"
        },
        "editform" : {
            "rel" : "edit-form",
            "href" : "/orders/1/editform"
        }
}
create-form and edit-form rel have well defined behavior described in IANA Link Registry

In one of my project based on Spring and AngularJS, the create form and edit form share the same template. When the user clicks "New" button returns create-form, it is a same template when user clicks "Edit" button.

In the Angular router configuration file, /orders/:id will redirected to the DETAIL page, which is a form used for creating and editing an order.

Say request GET /orders/123 will get the order information whose id is equals to 123, and these information will be rendered in the DETAIL page.

If the metadata of the create-form resource the same to domain resource, in my view, the URIs for create form and edit form can be simplified to one URI as /orders/createform OR /orders/editform, OR even /orders/:id in my case. So how to distinguish the form is used for creating or editing if I use /orders/:id in my project?

At first, I adopt the RFC 6861 and create a new URL /orders/createform to show the DETAIL page for creating an order, it means that I have to add a new controller to process the added endpoint. However, the URI structure of /orders/createform and /orders/:id is the same, so I modified the current method processing /orders/:id by changing the URI of /orders/createform to /orders/0 to response to the user with the intuition to create an order. SO in:
/orders/:id, if :id equals to 0, it means create a new order, otherwise, it means edit an existing order.
(OR you can use something like /orders/-1 to indicate creating option, for an id > 0)

After filling in the form and clicking the SAVE button, which will be:
PUT /order/:id
in the backend method, if id = 0 will create a new order and returned 201 Created , and if id>0 will update the order.

So the create and update option is processed in one method, without seperating as two methods, say POST /orders for creating and UPDATE /orders/:id for updating, cause PUT can also be used for create a resource and POST can also be used for updating a resource.
======================================================
The fundamental difference between the POST and PUT methods is
   highlighted by the different intent for the enclosed representation.
   The target resource in a POST request is intended to handle the
   enclosed representation according to the resource's own semantics,
   whereas the enclosed representation in a PUT request is defined as
   replacing the state of the target resource.  Hence, the intent of PUT
   is idempotent and visible to intermediaries, even though the exact
   effect is only known by the origin server.

   Proper interpretation of a PUT request presumes that the user agent
   knows which target resource is desired.  A service that selects a
   proper URI on behalf of the client, after receiving a state-changing
   request, SHOULD be implemented using the POST method rather than PUT.
   If the origin server will not make the requested PUT state change to
   the target resource and instead wishes to have it applied to a
   different resource, such as when the resource has been moved to a
   different URI, then the origin server MUST send an appropriate 3xx
   (Redirection) response; the user agent MAY then make its own decision
   regarding whether or not to redirect the request.

   A PUT request applied to the target resource can have side effects on
   other resources.  For example, an article might have a URI for
   identifying "the current version" (a resource) that is separate from
   the URIs identifying each particular version (different resources
that at one point shared the same state as the current version
   resource).  A successful PUT request on "the current version" URI
   might therefore create a new version resource in addition to changing
   the state of the target resource, and might also cause links to be
   added between the related resources.

   An origin server that allows PUT on a given target resource MUST send
   a 400 (Bad Request) response to a PUT request that contains a
   Content-Range header field (Section 4.2 of [RFC7233]), since the
   payload is likely to be partial content that has been mistakenly PUT
   as a full representation.  Partial content updates are possible by
   targeting a separately identified resource with state that overlaps a
   portion of the larger resource, or by using a different method that
   has been specifically defined for partial updates (for example, the
   PATCH method defined in [RFC5789]).

   Responses to the PUT method are not cacheable.  If a successful PUT
   request passes through a cache that has one or more stored responses
   for the effective request URI, those stored responses will be
   invalidated (see Section 4.4 of [RFC7234]).
=========================================================

What is your solution of URI designing for create-form and edit-form resource?