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

Tuesday, 30 May 2017

Spring Boot Test


An integration test, @SpringBootTest, load the whole of Spring application context. According to observations from the output. It initiates a database connection and a real web server listening on the ports (I see a Tomcat server starts on the port 8080). However,  via @SpringBootTest attributes, the web environment can be re-configured. By default, the web environment should be mock. On such a setup, a mocked servlet container is initiated, rather than a real application server. 

Two major annotations construct a typical Spring Boot (I am using 1.5 release right now) integration test. It looks like this:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class MyTest {

    // ...
    
}
  • @RunWith(SpringRunner.class) tells JUnit to run using Spring’s testing support. SpringRunner is the new name for,SpringJUnit4ClassRunner it’s just a bit easier on the eye. 
  • @SpringBootTest is saying “bootstrap with Spring Boot’s support” (e.g. load application.properties and give me all the Spring Boot goodness)
  • The attributewebEnvironment allows specific “web environments” to be configured for the test. You can start tests with a MOCK servlet environment or with a real HTTP server running on either a RANDOM_PORT or a.DEFINED_PORT  
  • If we want to load a specific configuration, we can use the attributeclasses of @SpringBootTest. In this example, we’ve omitted meansclasses that the test will first attempt to load @Configuration from any inner-classes, and if that fails, it will search for your primary @SpringBootApplication class.
There is another way to test without a server on but having the whole of Spring context(I can see all controller and its method having been mapped.), i.e. using @AutoConfigureMockMvc together with @SpringBootTest to inject a MockMvc instance. Spring uses this MockMVC to send HTTP requests into the DispatcherServlet, instead of a Test Rest Template),  and then hand it off to controllers. It explains there is no need to have a real server on. 

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ApplicationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void shouldReturnDefaultMessage() throws Exception {
        this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
                .andExpect(content().string(containsString("Hello World")));
    }
}
We may also test without turning sever on, and load partially Spring context(for a single controller). By this way, we may narrow down the test to a web layer alone,  by using @WebMvcTest.

@RunWith(SpringRunner.class)
@WebMvcTest
public class WebLayerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void shouldReturnDefaultMessage() throws Exception {
        this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
                .andExpect(content().string(containsString("Hello World")));
    }
}
  • When you start testing real systems, you often find it’s helpful to mock out specific beans. Common scenarios for mocking include simulating services that you can’t use when running tests, or testing failure scenarios that are difficult to trigger in a live system.
With Spring Boot 1.4 you can easily create a Mockito mocks that can replace an existing bean, or create a new one:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SampleTestApplicationWebIntegrationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @MockBean
    private VehicleDetailsService vehicleDetailsService;

    @Before
    public void setup() {
        given(this.vehicleDetailsService.
            getVehicleDetails("123")
        ).willReturn(
            new VehicleDetails("Honda", "Civic"));
    }

    @Test
    public void test() {
        this.restTemplate.getForEntity("/{username}/vehicle", 
            String.class, "sframework");
    }

}
In this example we’re:
  • Creating a Mockito mock for VehicleDetailsService.
  • Injecting it into the ApplicationContext as a bean using @MockBean
  • Injecting it into the field in the test.
  • Stubbing behavior in the setup method.
  • Trigger something that will ultimately call the mock.
Mocks will be automatically reset across tests. They also form part of the cache key used by Spring Test (so there’s no need to add @DirtiesContext)

Spies work in a similar way. Simply annotate a test field with @SpyBean to have a spy wrap any existing bean in the ApplicationContext.

What is Spring Application Context?


The ApplicationContext provides:

  • Bean factory methods for accessing application components.
  • The ability to load file resources in a generic fashion.
  • The ability to publish events to registered listeners.
  • The ability to resolve messages to support internationalization.
  • Inheritance from a parent context.



References: 
Spring Test Document

Building REST services with Spring

For understanding test in Spring boot, the following link is a good one.
Testing improvements in Spring Boot 1.4  






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