Monday, 28 August 2017

How Vaadin manage navigation in Spring Boot

Using Vaadin(GWT) front-end in the Spring boot.

Vaadin UI : it is a single component container, which holds a single layout component.
Vaadin View: it is a CustomComponent or a layout, while implementing vaadin view interface.

When using Vaadin with Spring boot, the above should be annotated by
@SpringUI and @SpringView respectively; so that it will be picked up in the Spring context.

When navigating between pages in Vaadin,  actually it is partially replaced by another view or the whole UI is replaced by another UI.

A Vaadin UI holds a navigator, and a SpringNavigatorProvider that manages the Vaadin views.
Navigator should be declared and instantiated in the UI. It should be associated with the
SpringNavigatorProvider.

As using Spring boot, SpringNavigatorProvider is auto-wired(injected).
Views will be automatically registered in the provider.





Vaadin Spring

Vaadin Spring Add-on

Vaadin Navigator Problem

View and Navigation

Vaadin Spring Code Example

Github vaadin-valo-demo

Wednesday, 23 August 2017

How to recover contributor in Github

One of my repository in the Github lost its contributor. I didn't see my avatar on the each commit.
The reason is due to I didn't give each commit a correct email address and name.

So I found the following URL;  by its instructions, I solved the problem.


Github Change Author Information

How to convert an image into byte array

Sometime we need to convert an image into byte array in order to persist it into database.

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author YNZ
 */
public class Image2Array {

    public static void main(String[] args) {
        byte[] imageArray = null;
        BufferedImage image = null;
        File file = new File("./src/tmp", "hit.jpg");
        try {
            image = ImageIO.read(file);
            try (ByteArrayOutputStream baos = new ByteArrayOutputStream(1024)) {
                System.out.println("write to buffer" + ImageIO.write(image, "jpg", baos));
                imageArray = baos.toByteArray();
                System.out.println("size of array " + imageArray.length);
                baos.flush();
            }

        } catch (IOException ex) {
            Logger.getLogger(Image2Array.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

Sunday, 20 August 2017

Thursday, 6 July 2017

Enable CROS at Spring


I developed a group Rest API and deployed at Heroku; however, it cannot be invoked from another domain for violating the same origin principle. It is a kind of security setup.

So I tried to use Spring @CrossOrigin to enable at rest controller or method level. However, it doesn't work well.

Therefore, I switched to a classical way, where I created a filter to modify the response header in order to enable CORS. It works well now.

In the Spring boot, a filer can be annotated as a component, thus it will be automatically picked up as the moment Spring context is initialized.

The reason because:

Spring MVC provides fine-grained support for CORS configuration through annotations on controllers. However, when used with Spring Security, we advise relying on the built-in CorsFilter that must be ordered ahead of Spring Security’s chain of filters.


What is CORS

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos.

The following diagram illustrates the Spring MVC's working flow,i.e. how a request received from the client is dispatched internally to controllers and send back to the client in response.

There is one way where we intercept all responses and modify their headers to enable CORS.





Cross-Origin Resource Sharing (CORS)

Spirng MVC 4 CORS Setup

Enable CORS in Spring Boot (in a filter)

Understanding CORS


Spring CORS controller annotation not working

Spring @CrossOrigin does not work with DELETE method

Thursday, 22 June 2017

Java 8 new features

The main feature of Java 8, Lambda expressions, also called behaviour parameterization, it allows transferring code into methods. Another new feature, Method-reference gives a succinct and descriptive code.  


Lambda expression 

Mathematically, an expression with parameter variables has been called a Lambda expression.  
for instance: f(x,y)=x+2y

In programming, Lambda function stands for a function defined without a name (identifier). Before Java 8, in order to pass a function, we need to declare a class that implements an interface. By this way, a developer may pass a function wrapped in an object. It is expensive in some sense. 

So Java 8 introduces a lambda expression for cheaply passing a block of code around. Java compiler is becoming smarter and smarter. It may infer parameter types from a functional interface (one method interface). Don't be scared of this new term.  Actually, we have used it for a quite long time, for instance, Comparator or Comparable interfaces.  

As a known functional interface, by using the lambda expression, passing a function around can be greatly simplified. 

The following example, the comparing function can be directly passed as an argument parameter. I think it exactly follows the math definition, f(x,y)=x+2y

package Lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

/**
 *
 * @author YNZ
 */
public class UsingLambadaExpression {

    public static void main(String[] args) {
        List users = new ArrayList<>();
        users.add(new User("Mike"));
        users.add(new User("Jeppe"));
        users.add(new User("Yichun"));
        Collections.sort(users, (o1, o2) -> o1.getName().compareTo(o2.getName()));
        System.out.println("" + users);
    }

}

class User {

    private String name;

    public User(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return this.name;
    }
}
Note: You can add annotation or final modifier to the lambda parameters. Note: It is not legal for lambda to return a value in a branch. Note: Functional interface contains a single abstract method.

Lambda Expression 3 ingredients:
(1) a block of code; (2) parameters; (3) values for the free variables, which are not defined in the block and transferred by the parameters.

a block of code and values of free values is a closure. Actually, it is implemented as a transferring by an object has a single method, so the free values have been initialized within that instance.

Method Reference 

 is used to simply certain Lambda expression, for instance:
(x->System.out.println(x))
We know there is already existed a method that may exactly operate the parameter as expected. In this case Lambda expression can be greatly simplified by using method reference.
 System.out::println 
Constructor reference, it is just like method reference, but using something like Class::new. It invokes its constructor. It equivalent to the lambda expression,i.e.
 x-> new constructor(x) 
Constructor reference can be used with the array type, i.e. int[]::new, i.e.
 x-> new int[x] 

Friday, 16 June 2017

JEE Bean Validation

Starting from JEE 6, Java starts to offer bean validation annotations, which may constrain property values.

JEE bean validation provides built-in constrain annotations, and a way to build custom-constrains too.

Bean validation annotations define how to validate bean properties. However, the validation need to be triggered from externally.

Or using annotation @Valid before the request or response body.

If a javax.validation.ValidationException or any subclass of ValidationException except ConstraintValidationException is thrown, the JAX-RS runtime will respond to the client request with a 500 (Internal Server Error) HTTP status code.

If a ConstraintValidationException is thrown, the JAX-RS runtime will respond to the client with one of the following HTTP status codes:

500 (Internal Server Error) if the exception was thrown while validating a method return type

400 (Bad Request) in all other cases



@Valid may throw
ConstraintValidationException 


import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author YNZ
 */
public class LoginInfoIT {

    private final Logger logger;

    private static ValidatorFactory validatorFactory;
    private static Validator validator;

    public LoginInfoIT() {
        logger = LoggerFactory.getLogger(this.getClass());
    }

    @BeforeClass
    public static void setUpClass() {
        validatorFactory = Validation.buildDefaultValidatorFactory();
        validator = validatorFactory.getValidator();
    }

    @Test
    public void testEmailConstraintValidation() {
        logger.info("Test Email Pattern Validation! ");
        LoginInfo instance = new LoginInfo("zyc@gmail", "Obhh2017");
        Set> violations = validator.validate(instance);
        assertEquals(1, violations.size());
    }

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import lombok.Data;

/**
 *
 * @author YNZ
 */
@Embeddable
@Data
public class LoginInfo implements Serializable {

    @Pattern(regexp = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+"
            + "(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$",
            message = " invalid email address! ")
    @NotNull
    @Column(name = "LOGIN_NAME", unique = true)
    protected String email;




Reference:
JEE 7 Bean Validation

Can Jackson Deserialize Java Time ZonedDateTime

Yes, but must include JSR310. Thus ZonedDateTime can be deserialized directly from JSON response to POJO field. <dependency> <g...