Java 8 : Lambda Example
Lambda Expressions:
Lambda expressions are new and important feature of Java 8. They provide a clear way to represent one method interface using lambda expression. And they provide easy way to access Collection libraries for iterating, filter and extract data.
Example :
Syntax : (arg1, arg2) -> {body}
For Ex:
(int a, int b) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } //Old way of iterating Collection List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); for(Integer n: list) { System.out.println(n); } //New way with lambda: List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); list.forEach(n -> System.out.println(n));
Rules:
- It can have zero or more number of arguments.
- Parameters are separated by using comma
- Empty parenthesis are used to represent empty parameters eg : () -> System.out.println(“Hello World”);
- Curly braces for body is not mandatory if it contains only single statement, other wise it should enclosed with curly braces.
Program:
interface TestInterface{ void display(); } public class TestInterfaceImpl{ public static void main(String[] args){ TestInterface li = new TestInterface(){ public void display(){ System.out.println("Hello World"); } }; li.display(); } }
Here we used anonymous class to implement TestInterface and this interface has only one method, by using lambda expression without using anonymous class we can call the display() method
interface TestInterface{ void display(); } public class TestInterfaceImpl{ public static void main(String[] args){ //Old way: TestInterface old = new TestInterface(){ public void display(){ System.out.println("Old : Display method called!"); } }; old.display(); //New way with Lambda expression TestInterface li = () -> System.out.println("New : Display method called !"); li.display(); } }
This approach we regularly use in Java Swing, while adding an action to Swing Component we use ActionListener actionPerformed() method, ActionListener is an interface which has only one method called actionPerformed(),
//old way: button.addActionListener(new ActionListener()){ public void actionPerformed(ActionEvent e){ System.out.println("The button was clicked using old fashion code!"); } } //New way: button.addActionListener( (e) -> { System.out.println("The button was clicked. From lambda expressions !"); });
java.util.Runnable also has only one method public void run(), this also we can represent using lambda
//old way Runnable r = new Runnable(){ public void run(){ System.out.println("Runnable run method"); } } //New way with lambda expression Runnable r = ()->System.out.println("Runnable run method"); //So we can create Thread object like below Thread t = new Thread(()->{System.out.println("Runnable run method from lambda")});
Any interface which has only one method can be used with lambda expression instead of old anonymous inner class.
Thanks for reading.
Java RPC style Webservice with JAX-WS
We have to create two projects one is WebService server project and WebService client project, here client will call the methods of Server.
1. Creating Server project:
Create an interface with @WebService annotation, and annotate the method with @WebMethod whitch you wanted to expose as web service.
package com.java2practice.ws; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; @WebService @SOAPBinding(style = Style.RPC) public interface WebServiceInterface{ @WebMethod int sum(int firstNumber, int secondNumber); }
2. Create an implementation to the above interface like below
package com.java2practice.ws; import javax.jws.WebService; @WebService(endpointInterface = "com.java2practice.ws.WebServiceInterface") public class WebServiceImpl implements WebServiceInterface{ @Override public int sum(int firstNumber, int secondNumber) { return firstNumber + secondNumber; } }
3. Now we have to publish this webservice by using EndPoint.
package com.java2practice.ws; import javax.xml.ws.Endpoint; import com.java2practice.ws.WebServiceImpl; public class WebServicePublisher{ public static void main(String[] args) { Endpoint.publish("http://localhost:7777/webservice/testws", new WebServiceImpl()); } }
- When we run the above code, webservice will be published and can be accessed by using http://localhost:7777/webservice/testws URL.
- To see the generated WSDL file click http://localhost:7777/webservice/testws?wsdl. And the generated WSDL look like
<pre>-<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --> <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --> <definitions targetNamespace="http://ws.java2practice.com/" name="WebServiceImplService"><types/> <message name="sum"><part name="arg0" type="xsd:int"/><part name="arg1" type="xsd:int"/></message> <message name="sumResponse"><part name="return" type="xsd:int"/></message> <portType name="WebServiceInterface"><operation name="sum" parameterOrder="arg0 arg1"> <input wsam:Action="http://ws.java2practice.com/WebServiceInterface/sumRequest" message="tns:sum"/> <output wsam:Action="http://ws.java2practice.com/WebServiceInterface/sumResponse" message="tns:sumResponse"/> </operation></portType><binding name="WebServiceImplPortBinding" type="tns:WebServiceInterface"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/> <operation name="sum"><soap:operation soapAction=""/> <input> <soap:body use="literal" namespace="http://ws.java2practice.com/"/> </input> <output> <soap:body use="literal" namespace="http://ws.java2practice.com/"/> </output> </operation> </binding> <service name="WebServiceImplService"> <port name="WebServiceImplPort" binding="tns:WebServiceImplPortBinding"> <soap:address location="http://localhost:7777/webservice/testws"/> </port> </service> </definitions>
Our webservice server project is fine, now we have to create client program, for this we have to use wsimport command, this will be available in java.
- Go to command prompt and give wsimport it will show all the options which are there in wsimport, if it doesn’t show any thing set the path variable to jdk/bin.
- wsimport -keep http://localhost:7777/webservice/testws?wsdl -d D:\java2practice\Desktop\client
- It will generate the files, and copy those files to your IDE and create a client program like below.
package com.java2practice.ws; public class WebServiceClient { public static void main(String[] args) { WebServiceImplService service = new WebServiceImplService(); WebServiceInterface serviceInterface = service.getWebServiceImplPort(); int sum = serviceInterface.sum(10, 20); System.out.println("answer : "+sum);//outputs answer as 30 } }
Thanks for reading.
How to send multiple rows of data to Spring Controller
Common requirement would be sending multiple rows of data to Spring Controller.
We use @RequestParam String value to hold the single form field. But when we dealing with multiple rows @RequestParam String value won’t work.
If It is single row like below like below
S.NO | First Name | Last Name | Age |
1 | AAA | BBB | 23 |
We can use @RequestParam annotation to capture the form data:
public String saveEmployee(@RequestParam Integer sNo, @RequestParam String firstName, @RequestParam String firstName, @RequestParam Integer age){ //here we can access the form data. }
Suppose we have a form with multiple rows. Then We have to use @RequestParam String[] values,
Let’s see the example below:
S.NO | First Name | Last Name | Age |
1 | AAA | BBB | 23 |
2 | CCC | DDD | 24 |
3 | EEE | FFF | 28 |
And here is the Controller Code:
public String saveEmployees(@RequestParam Integer[] sNo, @RequestParam[] String firstName, @RequestParam[] String lastName, @RequestParam[] Integer age){ //first row data Integer sNo_0 = sNo[0]; String firstName_0 = firstName[0]; String lastName_0 = lastName[0]; Integer age_0 = age[0]; //second row data Integer sNo_1 = sNo[1]; String firstName_1 = firstName[1]; String lastName_1 = lastName[1]; Integer age_1 = age[1]; //third row data Integer sNo_2 = sNo[2]; String firstName_2 = firstName[2]; String lastName_2 = lastName[2]; Integer age_2 = age[2]; }
Thanks for reading.
How to start Weblogic Server when any one of the Data Source is down
Recently we came across an issue with Weblogic start up, we configured Weblogic server with multiple DataSources and one of our Database is down due to some network issue. Weblogic server is unable to start as one of the DataSource is down, but to delete the DataSource (not working one) we need to have Weblogic server started, To start the server every DataSource should work fine. It’s a deadlock.
Solution : All the DataSources related configuration files located in (beahome)\user_projects\domains\Your_Domain\config\jdbc, Copy the working DataSource details jdbc_url,username,pwd(it will be in encrypted format) and paste it in another DataSource configuration xml file which database is down.
Suppose we have two DataSources
- DATASOURCE_1
- DATASOURCE_2
If DATASOURCE_1 is not working, we can copy the jdbc-url, username,pwd from DATASOURCE_2 and paste it in DATSOURCE_1 configuration file.
And start weblogic server now, it will start normally.
What we did here is just manipulated weblogic with the same jdbc details with multiple DataSources, internally it will treat as multiple DataSources, but it will connect to only working database as we gave the jdbc details of this working database.
Though we have two DataSources named with DATSOURCE_1 and DATASOURCE_2, both are pointing to same database DATSOURCE_2.
Thanks for reading, hope it helps.
How to execute method with JSP EL tag?
Till JSP 2.1 by using property name on bean <c:out value=”${beanName.property}”/> we used to display the values, internally it will call getter method of that property and value will be printed to browser. But to execute a normal method which doesn’t have getter method or setter method is not possible till JSP 2.1.
if we write <c:out value=”${beanName.methodName}”/> it will throw an error saying : getMethodName is not existing in type beanName.
But from JSP 2.2 on wards we can write <c:out value=”${beanName.methodName}”/> and it will execute the method internally and outputs the results to browser.
This feature is available in Servlet 3.0 environment, Tomcat 7 implementing Servlet 3.0 so we can run this code in Tomcat 7.
Thanks for reading
Javascript : modular pattern
While writing javascript code as a beginner we just write
function hello(){ alert('hello world'); }
but some problems occur with this approach, when we include multiple js files. All the variables which are declared outside any function will be treated as global and can be accessed from any function. And all the functions in all the js files are local to each other that means we can call any function from any js file, there is no concept of private function or we can not hide any function from being called.
With Javascript modular pattern we can avoid all these.
In this pattern we assign an anonymous function to global variable and all the functions declared inside can be called by using the variable name and the function name.
var app = (function (){ })();
Here app is the global variable and an anonymous function is assigned to it.
var app = (function (){ return { publicFun : function(){ alert('public function'); } }; })();
Declared a function with name publicFun, to access this function we have to call with global variable name app.publicFun(); and it will alert with “public function”.
Private functions: Whatever the functions we returned from the anonymous function can be accessed by using app global variable.
If we declare any function before return function, that will be called as local function and can not accessed with app variable.
var app = (function (){ function privateFun(){ alert('private function'); } return { publicFun : function(){ alert('public function'); } }; })();
If we call app.privateFun(); will give an error : TypeError: app.privateFun is not a function
So these private functions can not be accessed out side of the anonymous block. But we can call these in side any other public function.
var app = (function (){ function privateFun(){ alert('private function'); } return { publicFun : function(){ privateFun(); alert('public function'); } }; })();
Now app.publicFun() will internally call private function and will get private function alert followed by public function. Thanks for reading, hope you enjoyed it.
Spring Securty 3.2 with Custom Service
user table
CREATE TABLE 'user' ( 'user_id' int(11) NOT NULL AUTO_INCREMENT, 'user_name' varchar(250) NOT NULL, 'password' varchar(250) DEFAULT NULL, PRIMARY KEY ('user_id','user_name') ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
role table
CREATE TABLE 'role' ( 'role_id' int(11) NOT NULL AUTO_INCREMENT, 'role_name' varchar(250) NOT NULL, PRIMARY KEY ('role_id','role_name') ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
user_role join table
CREATE TABLE 'user_role' ( 'user_id' int(11) NOT NULL, 'role_id' int(11) NOT NULL, PRIMARY KEY ('user_id','role_id') ) ENGINE=InnoDB DEFAULT CHARSET=latin1
user and role has many to many relationship, and joining table is user_role
User.java
package com.java2practice.springsecurity.model; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name="user") public class User { @Id @GeneratedValue @Column(name="user_id") private Integer userId; @Column(name="user_name") private String userName; @Column(name="password") private String password; @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "USER_ID", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID", nullable = false, updatable = false) }) private Set<Role> userRoles = new HashSet<Role>(0); public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Role> getUserRoles() { return userRoles; } public void setUserRoles(Set<Role> userRoles) { this.userRoles = userRoles; } }
Role.java
package com.java2practice.springsecurity.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="role") public class Role { @Id @GeneratedValue @Column(name="role_id") private Integer roleId; @Column(name="role_name") private String roleName; public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } }
UserDao.java
package com.java2practice.springsecurity.dao; import javax.annotation.Resource; import org.apache.log4j.Logger; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Restrictions; import com.java2practice.springsecurity.model.User; public class UserDao { Logger logger = Logger.getLogger(this.getClass()); @Resource SessionFactory sessionFactory; public User getUser(String userName){ logger.info("getUser called"); Session session = null; try{ session = sessionFactory.openSession(); User user = (User) session.createCriteria(User.class). add(Restrictions.eq("userName", userName)).uniqueResult(); return user; }catch (Exception e) { e.printStackTrace(); return null; } } }
Our service has to implement org.springframework.security.core.userdetails.UserDetailsService
it has one method
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
this method returns org.springframework.security.core.userdetails.UserDetails
UserDetails user = new User(“username”, “password”,true, true, true, true, authorities);
like this we can convert our User to Spring UserDetails.
UserDetailsServiceImpl.java
package com.java2practice.springsecurity.service; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import com.java2practice.springsecurity.dao.UserDao; import com.java2practice.springsecurity.model.Role; @SuppressWarnings("deprecation") public class UserDetailServiceImpl implements UserDetailsService{ Logger logger = Logger.getLogger(getClass()); @Autowired UserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { try{ logger.info("loadUserByUsername "); com.java2practice.springsecurity.model.User userFromDB = userDao.getUser(username); logger.info("got user from database "+userFromDB); List<GrantedAuthorityImpl> authorities = new ArrayList<GrantedAuthorityImpl>(); for(Role role : userFromDB.getUserRoles()){ authorities.add(new GrantedAuthorityImpl(role.getRoleName())); } UserDetails user = new User(userFromDB.getUserName(), userFromDB.getPassword(), true, true, true, true, authorities); return user; }catch(Exception e){ logger.error("error "+e); return null; } } }
WebController.java
package com.java2practice.springsecurity.controller; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class WebController { Logger logger = Logger.getLogger(this.getClass()); @RequestMapping("/home") public String home(){ logger.info("webcontroller"); return "home"; } }
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <context:annotation-config /> <context:property-placeholder location="classpath:db.properties" /> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.user}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="com.java2practice.springsecurity.model" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> </props> </property> </bean> <!-- A custom service where Spring will retrieve users and their corresponding access levels --> <bean id="userDetailServiceImpl" class="com.java2practice.springsecurity.service.UserDetailServiceImpl" autowire="byName" /> <bean id="userDao" class="com.java2practice.springsecurity.dao.UserDao" autowire="byName" /> <!-- This is where we configure Spring-Security --> <security:http auto-config="true" use-expressions="true"> <security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/home.html" /> </security:http> <!-- Declare an authentication-manager to use a custom userDetailsService --> <security:authentication-manager> <security:authentication-provider user-service-ref="userDetailServiceImpl"> </security:authentication-provider> </security:authentication-manager> </beans>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.java2practice.springsecurity.controller" /> <context:annotation-config /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Spring4MVC</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> </web-app>
login.jsp
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1> <c:if test="${param.error}"> Error occurred ${param.error } </c:if> </h1> Login <form action="j_spring_security_check" method="post"> <p> <label for="j_username">Username</label> <input id="j_username" name="j_username" type="text" /> </p> <p> <label for="j_password">Password</label> <input id="j_password" name="j_password" type="password" /> </p> <input type="submit" value="Login" /> </form> </body> </html>
home.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Home</title> </head> <body> <h1>Welcome to Spring Security</h1> </body> </html>
Project Structure
SQL Joins explained in simple terms
Joins are used to join two or more tables in SQL based on the common data.
In this post I have explained below joins
1. Inner Join
2. Left outer join
3. Right outer join
Example: Let’s say we have an Employee table and Department table. Where every employee is associated with Department, new employees many not have Department.
And Every Department will have employees, for new Department, employees may not be there.
Department Table with data:
Employee table with data:
Here department_id is the foreign key to Department table, Department 3 doesn’t have any employees associated with it. And Employees 4,5 are not associated with any Department.
Now will perform different type of joins and examine the results:
1. Inner Join: Intersection of two tables is called inner join, Only the matched data will be returned from the two tables
Query: select e.*, d.* from employee e inner join department d on e.department_id = d.id
Resulted data :
The employees who doesn’t have any department and Department which doesn’t have employees won’t be returned.
In Venn diagram it looks like this:
2. Left outer join: returns all the data from the left table and only matched data from the right table.
Query: select e.*, d.* from employee e left outer join department d on e.department_id = d.id
Resulted data :
Returns all the 5 records from the Employee table and only 3 records from the Department table.
In the place of Department details for the employees 4,5( who doesn’t have department associated ) gives NULL values:
Venn diagram looks like this:
If we do left outer join from Department to Employee the result would be:
Query: select d.*, e.* from department d left outer join employee e on d.id = e.department_id
Resulted Data:
Returns all the data from Department table and in the place of employee details for Department 3 gives NULL values:
3. Right Outer Join:
Returns all the data from right side table and only matched data from the left side table.
Query: select e.*, d.* from employee e right outer join department d on e.department_id = d.id
Resulted data:
Returned all records from Department table and NULL values in the place Department 3 as no employees associated with it.
Venn diagram looks like this:
Thanks for reading.
Spring @Cacheable and @CacheEvict explained in simple terms
In Spring 3.1 we have a feature called Caching, It caches the data based on java method execution, if the java method executed before with same parameters it returns the cached data, other wise it will execute the method and puts the data into cache.
To enable caching :
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <cache:annotation-driven /> //your beans </beans>
<cache:annotation-driven /> Will recognize the spring cache annotations @Cacheable and @CacheEvict
Spring cache provides
@Cacheable annotation and @CacheEvict annotation.
Put @Cacheable on the method which you want to cache.
Ex:
@Cacheable(value="messagecache", key="#id", condition="id < 10") public String getMessage(int id){ return "hello"+id; }
Here getMessage() method is marked with @Cacheable, whenever getMessage() is called it will check the messagecache, if the data is already in messagecache it will return that otherwise it will executes the getMessage() and returns data.
@Cacheable annotations has 3 attributes
- Value : is the cache name and it is mandatory, in example it is “messagecache”
- Key: based on this data will be cached and it is optional
- Condition: based on the condition data will be cached. In example if the id < 10 then only data will be cached otherwise won’t. it is optional
@CacheEvict annotation will be used to delete the data from existing cache.
@CacheEvict(“employees”)
public void saveEmployee(Employee e){
}
Here whenever a saveEmployee() is called cache will be deleted.
@CacheEvict has 5 attributes:
- Value, 2 Key, 3 condition are similar to @Cacheable, apart from these 3 we have another 2 attributes
- allEntries : is a Boolean type and delete entire cache
- beforeInvocation: is Boolean type and will delete the cache before the method execution
Will go through one small example:
In this example I have used ehcache, refer www.ehcache.org for more information
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Scans within the base package of the application for @Components to configure as beans --> <context:component-scan base-package="com" /> <!-- Process cache annotations --> <cache:annotation-driven /> <!-- Configuration for using Ehcache as the cache manager--> <bean id="cacheManager" p:cache-manager-ref="ehcache"/> <bean id="ehcache" p:config-location="classpath:ehcache.xml"/> <bean id="employee" class="com.java2practice.model.Employee"/> </beans>
ehcache.xml
<ehcache> <diskStore path="java.io.tmpdir"/> <cache name="employeeCache" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> </ehcache>
Employee pojo:
package com.java2practice.model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.annotation.Cacheable; public class Employee { Logger logger = LoggerFactory.getLogger(getClass()); @Cacheable(value="employeeCache", key = "#id") public String getEmployee(Integer id){ logger.info("get employee called"); return "employee"+id; } }
This Employee class is injected into controller:
Controller :
package com.java2practice.web; import java.util.HashMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.java2practice.model.Employee; @Controller public class WebController { @Autowired Employee employee; @RequestMapping("/index.htm") public String homePage(@RequestParam(required= false) Integer id, HashMap<String, String> map){ map.put("message", employee.getEmployee(id)); return "index"; } }
And finally here is my JSP code:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Cache Example</title> </head> <body> <h1>This is ${message }</h1> </body> </html>
First time for the URL : http://localhost:8080/springcache/index.htm?id=1
Employee class getEmployee() method will be executed and data will be placed in cache. second time for the same request with id=1 getEmployee() method wont be executed, this can be seen by using the log message “get employee called” prints only for the first time.
And for the http://localhost:8080/springcache/index.htm?id=2
getEmployee() will be called and data will be placed in cache.
Here id is the Key, if id changes method will be executed and data will be placed in cache with the key.
When ever the requests comes for the @Cacheable annotated method, spring will check the key in corresponding cache if the cache has key in it. data will be returned from the cache other wise method will be executed.
Instead of ehcache we can use Spring SimpleCacheManager also:
<!-- Configuration for using SimpleCacheManager as the cache manager--> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager" > <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="employeeCache"/> </set> </property> </bean>
Add LinkedIn Sign In button through Javascript API
Before integrating with Linkedin javascript API we need to register our application with Linkedin.
To do this go to https://www.linkedin.com/secure/developer, in the Javascript domains add your application URL, localhost is accepted
Below code will describes how to add linkedin sign in button to your application.
Sample JSP file:
<!-- 1. Include the LinkedIn JavaScript API and define a onLoad callback function --> api_key: your_api_key scope: r_network,r_emailaddress,r_fullprofile,r_basicprofile,r_contactinfo <!-- need to be logged in to use Search; if not, offer a login button -->
That’s it, linkedin sign in button will appear in your page, if you click on it based on the scope it will ask your permissions.
For searching people from your application , we have to use Linkedin People Search API
To use linkedin search API, i have developed small program. It will ask for first name and last name, based on the given data it will search in linked in and prints the result in UI.
LinkedIn JavaScript API Hello World <!-- 1. Include the LinkedIn JavaScript API and define a onLoad callback function --> api_key: your_api_key scope: r_network,r_emailaddress,r_fullprofile,r_basicprofile,r_contactinfo function searchClick() { alert($("#firstNameId").val()+":"+$("#lastNameId").val()); if (!IN.ENV.auth.oauth_token) { alert("You must login w/ LinkedIn to use the Search functionality!"); return; } IN.API.PeopleSearch() .fields("id", "firstName", "lastName","emailAddress","headline","industry","pictureUrl","positions", "summary","numConnections") .params({ "first-name": $("#firstNameId").val(), "last-name": $("#lastNameId").val(), "count":25 }) .result(function(result, metadata) { setSearchResults(result.people.values); }); } function setSearchResults(values) { var table = $("#resulttable"); table.append(' <tr> <th>First Name</th> <th>Last Name</th> <th>Head Line</th> <th>Industry</th> <th>Picture</th> <th>No Of Connections</th> <th>Summary</th> <th>Positions</th> </tr> '); for (i in values) { try{ var person = values[i]; var positionsStr = " <ul>"; for(i in person.positions.values){ positionsStr+=" <li>"+person.positions.values[i].company.name+"</li> "; } console.log(positionsStr); table.append(' <tr> <td>'+ person.firstName+'</td> <td>'+ person.lastName+'</td> <td>'+ person.headline+'</td> <td>'+ person.industry+'</td> <td><img src="'+ person.pictureUrl+'" /></td> <td>'+ person.numConnections+'</td> <td>'+ person.summary+'</td> <td>'+ positionsStr+'</ul> </td> </tr> ') }catch(err){alert(err);} } } <!-- need to be logged in to use Search; if not, offer a login button --> <div align="right"> </div> Basic test of the People Search API via Connect. First Name: Last Name: <table id="resulttable"></table>
Thats it, for further info regarding Linkedin API http://api.linkedin.com/