Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Monday, July 16, 2018

BeanExpressionContext' - maybe not public or not valid?

Property or field 'xxxxxxxxx' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?

The solution is just you should read value like below.

@Value("${your.prop.name}")
private List<String> userIdList;

I just removed # symbol from there and its working fine as expected.

Thursday, May 19, 2016

Spring MVC Tutorial part IV - How to use RequestParam annotation

@RequestParam

It will be used in query string to bind the parameter with controller method parameters. We can see some possibility way of using request param.

1. Simple Request Param

@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam("orderDevice") String device,
                             Model model) {
    return "orderDetails";
  }

In the above method, the URI will be formed like /order/details?orderDevice=Laptop and where Laptop is value of orderDevice argument.

2. Request Param with Required attribute

@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam("orderDevice", required=false)
                             String device, Model model) {
    return "orderDetails";
  }  

If the value is missing for the orderDevice parameter, which value will be set to null,  else value will be passed as usual.

Note:
Required attribute default value is True. If the parameter is missing status code 400 will be returned.

3. Request Param with Default value

@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam("orderDevice",
                       defaultValue="MobileDevice") String device, Model model) {
    return "orderDetails";
  }

If the value is missing for the orderDevice parameter, which value will be set to MobileDevice as a default value.

4. Request Param with multiple param values

@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam("orderDevice") String device, 
                       @RequestParam("deviceId") String deviceId, Model model) {

   model.addAttribute("msg", "Order device and its Id : "+
                                                 device+", "+deviceId);
   return "orderDetails";
  }

Above will be mapped to /order/details?orderDevice=Laptop&deviceId=123

5. Request Param with Map object

@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam Map<String, String> queryMap,
                             Model model) {

   String device = queryMap.get("orderDevice");
   int deviceId = queryMap.get("deviceId");

   model.addAttribute("msg", "Order device and its Id : "+
                                                 device+", "+deviceId);
   return "orderDetails";
  }

From the above, both orderDevice and deviceId mapped to Map object with the help of requestParam annotation. So you access with Map object like above code.

URI will be like /order/details?orderDevice=Laptop&deviceId=123

6. Request Param with possibility ambiguous

@Controller
@RequestMapping("/Electronics")
public class ElectronicsController {

@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam("orderDevice") String device, 
                              Model model) {

   return "orderDetails";

  }


@RequestMapping(value = "/order/details", method = RequestMethod.GET)
  public String orderDetails(@RequestParam("deviceId") String deviceId, 
                              Model model) {

   return "orderDetails";

  }
}

Above method make Run time exception, since complain about ambiguous mapping. Exception is look like Caused by: java.lang.IllegalStateException: Ambiguous mapping.

Tuesday, May 17, 2016

Spring MVC Tutorial part III - How to use pathVariable annotation

@PathVariable Annotation

We can make dynamic URIs with the help of PathVariable annotation. You can map this pathVariable argument with Map object. Let us check below code. 

@Controller

 public class orderController {

 @RequestMapping("/orderDetails/{orderName}")
        public String showOrder(Model model, @PathVariable("orderName") String orderName) {

             model.addAttribute("orderName", orderName);

             return "showOrder"; // view name
     }
 }

From the above , the URI will from like below. Just assume you are running locally,

For Laptop order, URI like below,
http://localhost:8080/orderDetails/LaptopOrder

For Desktop order, URI like below,
http://localhost:8080/orderDetails/DesktopOrder

Some people may get confuse about request param and pathVariable. Both are different. Above URI is the example for pathVariable.
Below is the example for request param . 
http://localhost:8080/orderDetails?orderName=LaptopOrder

@PathVariable with Map

@RequestMapping(value="/{orderName}/{userName}",method=RequestMethod.GET)
public String getOrderUserName(@PathVariable Map<String, String> pathVars, Model model) {

    String name = pathVars.get("userName");
    String order = pathVars.get("orderName");

    model.addAttribute("msg", "Test" + name + " Spring MVC " + order);
    return "home";// ViewName
}

From the above, we have used Map<String, String> to map pathVariables for orderName and userName. After that, whenever data need , you can retrieve from pathVars map object.

Note: 

<mvc:annotation-driven /> needs to be added into your dispatcher-servlet.xml file. It will give an explicit support for mvc controllers annotation. Means, @RequestMapping, @Controller etc.,

<context:annotation-config> - It will support @Autowired, @Required , @PostConstruct etc.,

Spring MVC Tutorial Part II - Hello World Example

Spring MVC Hello World

Topics covered
1. Create Maven Project
2. Spring Dependency by Maven pom
3. Web.xml
4. Controller class
5. Displaying Views

Maven Project Creation

Create a new maven project called SpringMVC in eclipse. File --> new --> other --> Maven Project. After creating maven project , add tomcat as your application server in eclipse.

pom.xml

All the dependencies should be added here for Spring MVC configuration.  pom.xml code is below.
 
<project 
        xmlns="http://maven.apache.org/POM/4.0.0" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
        http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.javahit</groupId>
 <artifactId>SpringMVC</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>SpringMVC Hellow World</name>
 <url>http://maven.apache.org</url>

 <!--Spring version -->
 <properties>
  <spring.version>4.2.1.RELEASE</spring.version>
 </properties>

 <dependencies>

  <!-- Spring dependencies Start-->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <!--Spring dependencies End-->
 </dependencies>
 <build>
  <finalName>SpringMVC</finalName>
 </build>
</project>

web.xml with Dispatcher Servlet

<web-app>
 
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
 </context-param>

 <listener>
  <listener-class>
   org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>

 <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>/SpringMvc/*</url-pattern>
 </servlet-mapping>
</web-app>

dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

 <context:component-scan base-package="com.javaHit.controller"/>

 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix">
   <value>/WEB-INF/views/</value>
  </property>
  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>
</beans>

Controller Class

        package com.javaHit.controller;

 import org.springframework.stereotype.Controller;

 import org.springframework.ui.ModelMap;

 import org.springframework.web.bind.annotation.RequestMapping;

 import org.springframework.web.bind.annotation.RequestMethod;

  

 @Controller

 @RequestMapping("/helloWorld")

 public class HelloWorldController {

         @RequestMapping(method = RequestMethod.GET)

         public String hello(ModelMap model) {  

             model.addAttribute("name", "Spring Hello World!");

             return "helloWorld";
               }

     }

Displaying Views

helloWorld.jsp

<html>

 <body>

     <h1>Spring MVC Test</h1>
     <h3>Name : ${name}</h3>

 </body>
   </html>

Run the Application

Hit the URL, http://localhost:8080/SpringMvc/helloWorld

localhost:8080   -- Your local host( tomcat)
SpringMvc         -- Configured in web.xml for dispatcher
helloWorld         --  To execute correct Controller class (Request Mapping)

From the controller class method output string "helloworld", it will add both prefix and suffix to execute view page.

Monday, May 9, 2016

Spring MVC Tutorial Part I

MVC Architecture

The Spring MVC frameworks provides a good concept Model View Controller architecture. Lets see the definition of MVC. Generally you may find different definitions for MVC.Its an web application development framework.

Model - Its the application data, and its just not only the data. It may have any logic which is produce data for your application.

View - It will rendering model data and generates the HTML output to the client browser.

Controller - Its the responsibility to process your requests with the help of model and passes to view for rendering.

The Dispatcher Servlet 

It will handle all the HTTP request and responses and It is integrated with spring IOC container so that it is using all the features of spring.

Dispatcher servlet is an servlet and Its inherited from HTTPServlet base class. We should declare and mapping all request which should be handled by Dispatcher servlet. Below is the web.xml code for Dispatcher Servlet.

<web-app>

    <servlet>
        <servlet-name>exampleTest</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>exampleTest</servlet-name>
        <url-pattern>/example/*</url-pattern>
    </servlet-mapping>

</web-app>
So in the above code, all request will come with /example will be handled by Dispatcher Servlet. Suppose if your application have both struts and spring framework means, you need to configure ActionServlet also in web.xml. Ok, fine. Now Dispatcher Servlet initialization job is done. Now spring MVC looks for a file name called  [servlet-name]-servlet.xml in the WEB-INF directory of your web application.

In the above configuration code we have used example as a servlet name , so your  [servlet-name]-servlet.xml file will be example-servlet.xml. You can put anything as servlet name which should be used with -servlet.xml

Suppose if you like to use customize [servlet-name]-servlet.xml, then you need to configure ContextLoadListener like below. 
<web-app>

<!---DispatcherServlet definition goes here --->

<context-param>
   <param-name>contextConfigLocation</param-name><param-value>/WEB-INF/Hello-servlet.xml</param-value></context-param>

<listener>
   <listener-class>
      org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>
</web-app>

[servlet-name]-servlet.xml (example-servlet.xml)

Code configuration is below for example-servlet.xml. It should be placed inside WEB-INF directory.

<context:component-scan base-package="com.javaHit"/>;
       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="prefix" value="/WEB-INF/jsp/" />
          <property name="suffix" value=".jsp" />
       </bean>
Here, InternalResourceViewResolver will be used to access any views page like JSP, HTML, XHTML etc.,  It extends UrlBasedViewResolver that has two property i.e prefix and suffix. So the URL of view page will be make with the help of this prefix and suffix.

For example,
prefix + viewname (return from ModelAndView object) + suffix = URL of view page

We can see later what is ModelAndView object. In shorten, ModelAndView will return one name like hello.
Then page will be prefix+hello+suffix menas, /WEB-INF/jsp/hello.jsp. Hope you got it.

Its advisable and good practice to use JSP under WEB-INF for security purpose. Means, through direct URL (Manual URL) it wont give access.

Controller 

 When request come, Dispatcher Servlet delegates the request to particular controller to executes the logic or functionality. To define controller class we need to use @Controller annotation. Next we need to use @RequestMapping annotation to map an URL for an entire class or particular method. I would like to add two sample code below to understand more on Request Mapping.

Sample I - @RequestMapping with class

Sample code below
@Controller
@RequestMapping("/hello")
public class HelloController{
 
}

/hello will be used as URI for this controller class. Here we used , GET method (RequestMethod.GET) to handle the HTTP request. 

@RequestMapping(value="/methodHello")
@ResponseBody
public String methodHello(){
    return "hello";
}

Here, value attributes provides the URI for which method should be executed. @ResponseBody will  return response as String. We can do more with this @RequestMapping like how to produce response how to consume input etc.,We can see these all later as a separate post.

Now You can understand more with the help of below diagram.

MVC
Spring MVC Architecture


Wednesday, April 27, 2016

Spring Bean Life Cycle

Spring Bean Life Cycle

Spring beans are managed by Spring IOC container. Various types of life cycle interfaces will be involved during bean life cycle by this container.

If any bean want to be used by application some initialization process needs to be followed and the same way for destroying some destroying process needs to follow. Spring container following some process and this process we are calling as Bean Life Cycle.

Flow Diagram Overview

Bean
Spring Bean Life Cycle Diagram

Order of Execution:

1. IOC container look for the spring bean definition in the configuration file.
2. Once find container will create instance of the bean by using Java Reflection API.
3. If any properties mentioned, it will be populated and Dependency will be injected.
4. If the bean implements InitializingBean interface then it should implements its method
 void afterPropertiesSet() throws Exception;
5. If the bean implements DisposbleBean interface then it should implements its method
void destroy() throws Exception;

The above process is looks like simple, but mostly its not recommended since it will create tight coupling.
6. If the bean implements any of the following Aware interfaces for the specific behavior, then that process will be started with its methods. See, if you are implements any of the following, then only it will be executed. 

1. ApplicationContextAware
2. ApplicationEventPublisherAware
3. BeanClassLoaderAware
4. BeanFactoryAware
5. BeanNameAware
6. LoadTimeWeaverAware
7. MessageSourceAware
8. NotificationPublisherAware
9. ResourceLoaderAware

Below sample code implementing all of above interfaces and overriding its methods.
public class TestBean implements ApplicationContextAware,
        ApplicationEventPublisherAware, BeanClassLoaderAware, BeanFactoryAware,
        BeanNameAware, LoadTimeWeaverAware, MessageSourceAware,
        NotificationPublisherAware, ResourceLoaderAware
{
    @Override
    public void setResourceLoader(ResourceLoader arg0) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setNotificationPublisher(NotificationPublisher arg0) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public void setMessageSource(MessageSource arg0) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setLoadTimeWeaver(LoadTimeWeaver arg0) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setBeanName(String arg0) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setBeanClassLoader(ClassLoader arg0) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher arg0) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        // TODO Auto-generated method stub
    }
}


7. Suppose in your configuration file, bean uses init-method attributes , then that method will be called. Sample configuration code below. 




    
  

8. Same way bean configuration uses default-destroy-method attributes , then that method will be called . Above sample configuration code have that.

Below is the simple custom init and destroy method.
public class TestBean 
{
    public void customInitmethod() 
    {
        System.out.println("Custom Init() invoked");
    }
 
    public void customDestroymethod() 
    {
        System.out.println("CustomDestroy() invoked");
    }
}

Tuesday, March 22, 2016

Spring + Maven + Log4j for HelloWorld

Log4j is very useful for developer to identify code flow logging information.

In this project I have used below tools and technologies.

1. Eclipse Indigo
2. Spring
3. Maven
4. Log4j

In previous section I have simply developed helloworld program with Spring and Maven. Here I am going to add just log4j configuration and its usage.

Since our application created through maven, we should add log4j dependency in pom.xml. I have mentioned group id , artifact id, scope and version for log4j. Here runtime scope indicates dependency is required at execution time only, not on compilation time.



  4.0.0
  com.test
  helloworld
  0.0.1-SNAPSHOT
  
  
  
   org.springframework
   spring-core
   ${spring.version}
  
  
   org.springframework
   spring-context
   ${spring.version}
  
  
   log4j
   log4j
   runtime
   ${log4j.version}
  
 
 
 
  3.2.3.RELEASE
  1.2.17
 
 


Create a log4j.properties file under src/main/resources. The below is log4j property file.

# LOG4J configuration

#You can set here different level like ALL,INFO,WARN etc.,
log4j.rootLogger=INFO, TestConsoleAppender, TestFileAppeneder
 
log4j.appender.TestConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.TestConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.TestConsoleAppender.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
 
log4j.appender.TestFileAppeneder=org.apache.log4j.FileAppender
log4j.appender.TestFileAppeneder.File=C:/logs/test.log
log4j.appender.TestFileAppeneder.layout=org.apache.log4j.PatternLayout
log4j.appender.TestFileAppeneder.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n

In above property file, I have configured root logger in INFO level with ConsoleAppender and FileAppender.

1. Added TestConsoleAppender for the purpose of console output to display in console tab.

2. Added TestFileAppeneder for the purpose of create a log file in your local drive. Suppose if you have web application, there is good way to add your log file with your web server. Just you need to change the path location to web server directory.

Finally, in our java code I added sayHello method that have all logging level possibilities.(TRACE,DEBUG,INFO,WARN,ERROR,FATAL).

Based on your log4j configuration only, log will be printed. For example, if you set rootlogger as ALL all log levels will be printed. But in our code I have set to INFO, so INFO,WARN, ERROR and FATAL will be displayed based on its hierarchy level. TRACE and DEBUG will not be printed.

Log4j Hierarchy Order

  • OFF
  • FATAL
  • ERROR
  • WARN
  • INFO
  • DEBUG
  • TRACE
  • ALL


For more info please visit Log4J levels details

Java code is below. 

package com.test.helloworld;

import org.apache.log4j.Logger;
 
//@Service("helloWorld")
public class HelloService {
 
 private static final Logger LOGGER = Logger.getLogger(HelloService.class);
 private String name;
 
 public void setName(String name) {
  this.name = name;
 }
 
 public String sayHello() {
  
  LOGGER.trace("Trace Message!");
  LOGGER.debug("Debug Message!");
  LOGGER.info("Info Message!");
  LOGGER.warn("Warn Message!");
  LOGGER.error("Error Message!");
  LOGGER.fatal("Fatal Message!");
  return "Hello ! Spring + Maven + Log4J Tested by " + name;
 }
}

Now we have to run HelloTest java code, the below out put you able to see in console tab, due to adding ConsoleAppender.

Note:  In my previous post, you can find HelloTest and application context xml code.

Spring_maven_log4j


At the same time, log file also generated at C:\logs location, since you provided in FileAppender configuration in log4j property file.

log4j

Thats All. Happy Learning!!!

Monday, March 21, 2016

Simple program with Spring + Maven

The below simple program developed with Spring and maven configuration.

Technologies used:

1.Eclipse Indigo
2.Jdk 1.6
3.Maven 3.0.4
4.Spring 3.2.3

Note: If any image is not able to see properly, please click on that image. It will show nice visible mode.

Step 1: Open eclipse, File àNew à Maven à Maven Project. Its look like below.

Maven
Step 2: Once you create maven project , select (tick) create a simple project. you will see the below in next screen. 

Simple Project
Step 3: Click Next. You will see below in next screen. Please provide Group Id and Artifact Id which is related to maven. Its look like below.

Here I provided,
Group Id : com.test
Artifact Id: helloworld

Group Id: It will identify your project uniquely across all your projects. It has to follow package name rules (Naming schema). 

Artifact Id: Project name as artifact id for the purpose of JAR. Always put frinedly name here.

POM xml
Step 4: Once you click finish on above screen , the next screen will appear like below. This is your project structure now.

Maven structure
Step 5: Please add the below in pom.xml. Here you can add all of your dependency, properties etc.,




  4.0.0
  com.test
  helloworld
  0.0.1-SNAPSHOT
  
  
  
   org.springframework
   spring-core
   ${spring.version}
  
  
   org.springframework
   spring-context
   ${spring.version}
  
 
 
 
  3.2.3.RELEASE
 
 


Step 6: Once you configured pom xml, next you should add application context xml for your project bean definition. So , create one xml like below under src/main/resources.

Spring context xml
Once xml file was created, add the below bean definitons.



 
  
 


Step7 : After adding application context xml, add your java class with the name of  HelloService. That java class looks like below.

package com.test.helloworld;

import org.springframework.stereotype.Service;
 
@Service("helloWorld")
public class HelloService {
 
 private String name;
 
 public void setName(String name) {
  this.name = name;
 }
 
 public String sayHello() {
  return "Hello ! Spring + Maven Test by " + name;
 }
}


Note: Here @Service annotation is not mandatory, without this also program will run. But in generally, its good to add before call will go from this class to any DAO class etc.,

Step 8: The above java class implemented at service layer level. So I used there @Service annotation. We can see it deeply later.

Now I need to test it, means should call above java class from HelloTest java class. The implemented class for HelloTest is below.

package com.test.helloworld;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloTest {
  
 
 public static void main(String[] args) {
 
  // loading bean definitions from applicationcontext.xml
  ApplicationContext context = new ClassPathXmlApplicationContext(
    "applicationContext.xml");
 
  HelloService service = (HelloService) context
    .getBean("helloWorld");
  String message = service.sayHello();
  System.out.println(message);
 
  //set your new name
  service.setName("Setting again new name : TestHelloWorld ");
  message = service.sayHello();
  System.out.println(message);
 }
}


Step 9 : Next we should and clean and build through maven. You can directly run this application from main method of HelloTest java. Since it is a maven project, it is advice to follow through clean and install maven option .

Right click on your pom xml or on project , select Run As --> Maven Clean.
Below images will explain clearly.

maven clean

Step 10 :  Once maven clean done, you should build the application.

Right click on your pom xml or on project , select Run As --> Maven Install. It will build your project. The below images will explain that.

install

Step 11: After build your project , you able to see below screen. In case if your project have any Test class(Junit) it will refelect in console tab.

console
Step 12: After finishing maven clean and install, Run your application .

Right click on HelloTest program, Run As --> Java application. Below output we can see.

Console Output
Please raise comment in case if you have any clarification.

Thats All. Happy learning!