Angular2 step by step 2 – How to install latest Node.js and NPM

By W.ZH Oct 2016

Install latest Node.js, from Node.js website:

First, make sure you have a C++ compiler. Open the terminal and install the build-essential and libssl-dev packages if needed. By default, Ubuntu does not come with these tools — but they can be installed in the command line.

Use apt-get to install the build-essential package and libssl-dev:

sudo apt-get install build-essential checkinstall

sudo apt-get install libssl-dev

You can install and update Node Version Manager, or nvm, by using cURL:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash

You will be asked to close and reopen the terminal. To verify that nvm has been successfully installed after you reopen the terminal, use:

command -v nvm

That command will output nvm if the installation worked.

To download, compile and install the latest version of Node:

 

Install latest NPM

There’s a pretty robust install script at https://www.npmjs.org/install.sh. You can download that and run it.

Here’s an example using curl:

curl -L https://npmjs.org/install.sh | sh


 

Angular2 step by step – 1. Install the Node.js

By W.Zh Oct 2016

Our history and current projects mostly based on the Java/Spring/JSP to do most things. And at the front end side, we use EasyUI, KendoUI, GoJS, Jquery,  and a little bit angular JS 1 to realize the page render, control and data loading. But with the Angular 2 released in last month, I have decided to start using the angular2 in future projects. As we already have the Spring controllers working as the RESTful service in system. so Front end in future will totally be detached from the Java server side easily!!!

Of course we are going to face many challenges  in future about the new tech pick up, old UI migration, interface integrations , but embracing the trend of the detached front end will benefit all teams and it will be fun, especially the Typescript and Angular2 natively have too much common with Java stacks.

I will start to write a series of articles about the angular2 when we adopt it. let us start from installing:

To install Node.js and npm,  in your terminal of Ubuntu:

$ node -v
$ npm -v

 

Two Contexts in Spring MVC applications – Application Context, WebApplicationContext

By W.ZH Sept 2016

If you directly start learning Spring from the Spring MVC. then you may be ignored a context issue. MVC works in a context called webapplicationcontext  or servlet context. besides this one spring itself already has a root context or application context. So there are some very important points you must be clear on these two:

  • Application Context default use this files as config file – applicationContext.xml . One web application only has one Application Context. Spring loads applicationContext.xml file and creates the ApplicationContext for the whole application. if you have more than one config files for the context, you can config them in the web.xml as the <context-param>:
<web-app ..... >
....
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml, classpath:spring-security.xml</param-value>
    </context-param>
...
</web-app>

  • Spring security is in the root context – Application Context, not in the WebApplicationContext
  • Each DispatcherServlet associated with single WebApplicationContext. There can be multiple WebApplicationContext in a single web application.each DispatcherServlet could have one xml config used. in Web.xml it looks like this:
     <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mvc-dispatcher.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
  • WebApplicationContext is a child of “ApplicationContext”, You can access bean in the root context from the WebApplicationContext, but you can not access the bean in the WebApplicationContext from root context.
  • WebApplicationContext contains the  controllers, RestControllers and view resolvers. Root context contains other services, components, DAO access  initialized by the ContextLoaderListener.
  • If you define a property-placeholder in one context, it can not be accessed from another context. This means if you have one properties files need be accessed by @Value in two context, you need to insert this piece config in both context’s xml file”
<context:property-placeholder location="classpath:myConfigProp.properties"
        ignore-resource-not-found="true" />

 

Refer to:

https://spring.io/understanding/application-context

http://hmkcode.com/spring-mvc-share-root-webapplicationcontext-beans-with-child-webapplicationcontext/

 

Spring security note – Create a simple authentication-manager by get user from DB table – 2

By WZH. Sept 2016

When you use the Spring Security, you system could save user define in many kinds of places, such as dummy test account , DB table, or LDAP. So you just need to have different user service supply to spring security’s  authentication-manager, as far as you meet the needs defined by the authentication-manager.

authentication-manager in fact needs a UserDetails object to contain the user name, password and Authorities. Here I show you one example that just use XML to define a DB access user service :

<security:authentication-manager id="directDBAuthManager">
        <security:authentication-provider>
            <security:password-encoder hash="md5" />
            <security:jdbc-user-service
                data-source-ref="myDataSource" id="userDetailsDBService"
                users-by-username-query="SELECT username, password, enabled FROM abc_DB.usertable WHERE username=?"
                authorities-by-username-query="SELECT username, role FROM abc_DB.usertable where username =?  " />
        </security:authentication-provider>
    </security:authentication-manager>

 

myDataSource is a datasource define in the spring, refer to datasource define docs. Then  you just need to use it at here to access DB.

users-by-username-query must be a SQL to return the user name , password and enable(true/false) in this order to the system(no need to be these names). So you can see that my DB of abc_DB has a table called usertable to contain the user data and return these data to system.

authorities-by-username-query in fact returns the user and and roles to the system to create the authorities.

Spring internal in fact uses there two query to get data and create the method of
public UserDetails loadUserByUsername(String username)  for the UserDetailsService.

<security:password-encoder hash=”md5″ /> this is a note that password format in fact is a MD5. So when the authentication-manager get the UserDetails, it will compare the login input’s password with password from UserDetails in the MD5 format.

id=”userDetailsDBService” – with this ID here, you can look up this bean by ID in the java code to call this UserDetailsService. so that when you need to UserDetails in java code, you can just call this user service directly.

Two or more authentication-manager in Spring security

By W.ZH Sept 2016

In Spring Security, you may need to two separate authentication-manager in system.  here is one example :

    <!-- Authentication manager 1 -->
    <security:authentication-manager id="userAuthenManager">
        <security:authentication-provider
            user-service-ref="userDetailsService">
            <security:password-encoder hash="md5" />
        </security:authentication-provider>
    </security:authentication-manager>
  
    <bean id="userDetailsService" class="com.abc.userdetails.UserDetailsServiceImpl" />

    <!-- Authentication manager 2 -->
    <security:authentication-manager id="dummyAuthenManager"> 
        <security:authentication-provider> 
            <security:user-service> 
                <security:user name="admin_user" password="password" authorities="ROLE_ADMIN" /> 
                <security:user name="normal_user" password="password" authorities="ROLE_USER" /> 
            </security:user-service> 
        </security:authentication-provider> 
    </security:authentication-manager>

 

So there is some special note you need to notice at here:

  1. Two or more authentication-manager must have respectively unique ID for them. So  that when you define the http security checker, you can use ID to define which authentication-manager is used. Like this:
    <security:http auto-config="true" use-expressions="true"
            authentication-manager-ref="userAuthenManager">
              。。。。。。。。。。。。。。。。。。。
        </security:http>
  2.  Order and others no special request.
  3. Normally when you create a authentication-manager, you must have have the user service  for it. they will have different user details service for it.
  4. To create a user service, you can use the dummy user hard code there(for testing only), like the dummyAuthenManager. or you can use a JDBC access the user details from DB tables. or you can implement a user service by your self by implement interface of org.springframework.security.core.userdetails.UserDetailsService, such as the UserDetailsServiceImpl in my example.  The jave code will like this in my example:

 

package com.abc.userdetails;

import javax.annotation.Resource;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.abc.dbservice.impl.UserInfoServiceImpl;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource(name = "userInfoService")
    private UserInfoServiceImpl userInfoService;
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        UserDetails user = userInfoService.searchByLoginId(username);
        if (user == null) {
            throw new UsernameNotFoundException(String.format(
                    "No user found with username '%s'.", username));
        } else {
            return user;
        }
    }
}

loadUserByUsername method is the only one you need to realize for this interface. and authentication-manager will call this method to get user, and then compare it with the user’s input name and password to do the authentication.

Implement the UserDetailsService inteface should be the best way for the user service as you can do a lot things in the UserDetailsServiceImpl code.

 

 

 

Solve the Json/Java polymorphism request by Jackson

By W.ZH

When convert between json and jave objects, you could often face the polymorphism issue.
Such as a json of Content could be:

{
  "type":"valuea",
  "value": {
    "valueaName": "corn",
    "bar":  "sweet"
  }
}

and also could be

{
  "type":"valueb",
  "value": {
    "valuebName": "toy",
    "color":  "yellow",
    "price":  "20"     
  }
}

Value objects in fact is depends on the type data to change. This requires that depending on the type data and create different value’s object at Java side, How to do?

Here is the solution at the Jackson code by using the     @JsonTypeInfo

let us define a abstract class Value and another two class ValueA and ValueB to Extends it.

public abstract class Value {
}

and ValueA to inherit Value

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ValueA extends Value {

    @JsonProperty("valueaName")
    private String valueaName = "";

    @JsonProperty("bar")
    private String bar;
....................................
....................................
}

and ValueB Class to inherit Value.

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ValueB extends Value {

    @JsonProperty("valuebName")
    private String valuebName = "";

    @JsonProperty("color")
    private String color;

    @JsonProperty("price")
    private String price;
....................................
....................................
}

 

Then after that we can create a Class for Content to let “type” files  work as a EXTERNAL_PROPERTY to control the Value object in side the Content:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Content {

    @JsonProperty("type")
    private String type;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("value")
    private Value value = null;
    
    public Content (){
    }
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
    @JsonSubTypes({ @Type(value = ValueA.class, name = "valuea"),@Type(value = ValueB.class, name = "valueb")})
    public void setValue(Value value) {
        this.value = value;
    }

    public Value getValue() {
        return value;
    }

}

In this way. @JsonTypeInfo in fact define how to rely on “type” to dynamically  serialize and de-serialize the json/java object.

To make this properly work, your Jackson version must higher than the 2.5 version. As I have faced the duplicated fields bug in the 2.5  version Jackson , here is sample dependency:

 

        <!-- Jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.0</version>
        </dependency>

 

 

Spring MVC + Security Note (4) – Migrate from Spring Security 3.X to 4.X

By W.ZH

Refer to this link

http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-xml.html

Here are some notes that common change in page or configuration files:

  1. default URL for login and logout form action are changed:
    /j_spring_security_logout     to /logout
    /j_spring_security_check     to /login
    So we need to change our JSP content for these two.
  2. Default csrf is enabled… so if you want to be disabled, just add this
    <csrf disabled=”true”/> in the <http />tag
    If you want enable, you do not need to do sth.
  3. <access-denied-handler error-page=”/page/403″ />  put inside the <http />
    not like old on as the attribute <http *** />
  4. If you have more than one roles, you can not use the
    access=”ROLE_USER,ROLE_ADMIN”  any more, you have to change to<http auto-config=”true” use-expressions=”true” >
    …..
    <intercept-url  ……. access=”hasAnyRole(‘ROLE_USER’,’ROLE_ADMIN’)” …..you maybe have others need changes, need to refer to reference page