Thursday, December 31, 2015

Can we define a bean with Prototype scope inside a bean with singleton scope in a spring context?

Yes, You can define.

But you will have only one instance created for the inner bean also even though it has prototype scope because it's being called from a outer bean which is in a singleton scope (default spring bean scope).

See the below example to understand in detail.

Project Structure:






App.java

package com.rajesh.common.controller;

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

import com.rajesh.common.bean.HelloWorld;

public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationcontext.xml");

HelloWorld obj = (HelloWorld) context.getBean("helloBean");
System.out.println("1st HelloWorld : " + obj);
System.out.println("1st HelloClass : "+obj.getHelloClass());
HelloWorld obj2 = (HelloWorld) context.getBean("helloBean");
System.out.println("2nd HelloWorld : " + obj2);
System.out.println("2nd HelloClass : "+obj2.getHelloClass());
obj.printHello();
}
}



HelloWorld.java

package com.rajesh.common.bean;

public class HelloWorld {
HelloClass helloClass;

public void printHello() {
helloClass.printHello();
}

public HelloClass getHelloClass() {
return helloClass;
}

public void setHelloClass(HelloClass helloClass) {
this.helloClass = helloClass;
}
}

HelloClass.java

package com.rajesh.common.bean;

public class HelloClass {

private String name;

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

public void printHello() {
System.out.println("Spring 3 : Hello ! " + name);
}


}


applicationcontext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">

<bean id="HelloClass" class="com.rajesh.common.bean.HelloClass" scope="prototype">
<property name="name" value="rajesh" />
</bean>
<bean id="helloBean" class="com.rajesh.common.bean.HelloWorld" >
<property name="helloClass" ref="HelloClass" />
</bean>

</beans>



Here is output of this program.

1st HelloWorld : com.rajesh.common.bean.HelloWorld@4dd36dfe
1st HelloClass : com.rajesh.common.bean.HelloClass@73da669c
2nd HelloWorld : com.rajesh.common.bean.HelloWorld@4dd36dfe
2nd HelloClass : com.rajesh.common.bean.HelloClass@73da669c
Spring 3 : Hello ! rajesh


Analysis : If you observe the above output, you have the same instance returned in both the places for the HelloClass bean even though it's defined with prototype scope because the Helloworld bean is defined with default scope (singleton) and hence the result.









Wednesday, December 30, 2015

The redirect: prefix and The forward: prefix

Ref:- http://docs.spring.io/spring-framework/docs/1.2.9/reference/mvc.html


13.5.3.2. The redirect: prefix

While the use of RedirectView works fine, if the controller itself is creating the RedirectView, there is no getting around the fact that the controller is aware that a redirection is happening. This is really suboptimal and couples things too tightly. The controller should not really care about how the response gets handled. It should generally think only in terms of view names, that have been injected into it.
The special redirect: prefix allows this to be achived. If a view name is returned which has the prefix redirect:, then UrlBasedViewResolver (and all subclasses) will recognize this as a special indication that a redirect is needed. The rest of the view name will be treated as the redirect URL.
The net effect is the same as if the controller had returned a RedirectView, but now the controller itself can deal just in terms of logical view names. A logical view name such as redirect:/my/response/controller.html will redirect relative to the current servlet context, while a name such as redirect:http://myhost.com/some/arbitrary/path.html will redirect to an absolute URL. The important thing is that as long is this redirect view name is injected into the controller like any other logical view name, the controller is not even aware that redirection is happening.

13.5.3.3. The forward: prefix

It is also possible to use a special forward: prefix for view names that will ultimately be resolved by UrlBasedViewResolver and subclasses. All this does is create an InternalResourceView (which ultimately does a RequestDispatcher.forward()) around the rest of the view name, which is considered a URL. Therefore, there is never any use in using this prefix when using InternalResourceViewResolver/InternalResourceView anyway (for JSPs for example), but it's of potential use when you are primarilly using another view technology, but want to still be able to in some cases force a forward to happen to a resource to be handled by the Servlet/JSP engine. Note that if you need to do this a lot though, you may also just chain multiple view resolvers.
As with the redirect: prefix, if the view name with the prefix is just injected into the controller, the controller does not have to be aware that anything special is happening in terms of handling the response.

What is @Configuration in Spring - Spring 3 JavaConfig example

Ref:- http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch03.html

Since Spring 3, JavaConfig features are included in core Spring module, it allow developer to move bean definition and Spring configuration out of XML file into Java class.
But, you are still allow to use the classic XML way to define beans and configuration, the JavaConfig is just another alternative solution.
See the different between classic XML definition and JavaConfig to define a bean in Spring container.
Spring XML file :
<beans xmlns="http://www.springframework.org/schema/beans"
 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-3.0.xsd">
 
 <bean id="helloBean" class="com.mkyong.hello.impl.HelloWorldImpl">
  
</beans>
Equivalent configuration in JavaConfig :
package com.mkyong.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mkyong.hello.HelloWorld;
import com.mkyong.hello.impl.HelloWorldImpl;

@Configuration
public class AppConfig {
 
    @Bean(name="helloBean")
    public HelloWorld helloWorld() {
        return new HelloWorldImpl();
    }
 
}

What is @Bean annotation in Spring

Ref:- http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch02s02.html


@Bean is a method-level annotation and a direct analog of the XML <bean/> element. The annotation supports most of the attributes offered by <bean/>, such as: init-methoddestroy-methodautowiringlazy-initdependency-checkdepends-on and scope.

2.2.1. Declaring a bean

To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory. By default, the bean name will be the same as the method name (see bean naming for details on how to customize this behavior). The following is a simple example of a @Bean method declaration:
@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }
}
                
For comparison sake, the configuration above is exactly equivalent to the following Spring XML:
<beans>
    <bean name="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
                
Both will result in a bean named transferService being available in the BeanFactory / ApplicationContext, bound to an object instance of type TransferServiceImpl:
transferService -> com.acme.TransferServiceImpl
                

2.2.2. Injecting dependencies

When @Beans have dependencies on one another, expressing that dependency is as simple as having one bean method call another:
@Configuration
public class AppConfig {
    @Bean
    public Foo foo() {
        return new Foo(bar());
    }

    @Bean
    public Bar bar() {
        return new Bar();
    }
}
                
In the example above, the foo bean recevies a reference to bar via constructor injection.

2.2.3. Receiving lifecycle callbacks

2.2.3.1. Using JSR-250 annotations

JavaConfig, like the core Spring Framework, supports use of JSR-250 "Common Annotations". For example:
public class FooService {
    @PostConstruct
    public void init() {
        // custom initialization logic
    }
}

@Configuration
@AnnotationDrivenConfig
public class ApplicationConfig {
    @Bean
    public FooService fooService() {
        return new FooService();
    }
}
                    
In the above example, FooService declares @PostConstruct . By declaring JavaConfig's @AnnotationDrivenConfig on The @Configuration class, this annotation will be respected by the container and called immediately after construction. See The core framework documentation on support for JSR-250 annotations for further details.

2.2.3.2. Using Spring interfaces

Spring's lifecycle callbacks are fully supported. If a bean implements InitializingBeanDisposableBean, or Lifecycle, their respective methods will be called by the container in accordance with their Javadoc.

2.2.3.3.  Using @Bean initMethodName / destroyMethodName attributes

The @Bean annotation supports specifying arbitrary initialization and destruction callback methods, much like Spring XML's init-method and destroy-method attributes to the beanelement:
public class Foo {
    public void init() {
        // initialization logic
    }
}
public class Bar {
    public void cleanup() {
        // destruction logic
    }
}
@Configuration
public class AppConfig {
    @Bean(initMethodName="init")
    public Foo foo() {
        return new Foo();
    }
    @Bean(destroyMethodName="cleanup")
    public Bar bar() {
        return new Bar();
    }
}
                    
Of course, in the case of Foo above, it would be equally as valid to call the init() method directly during construction:
@Configuration
public class AppConfig {
    @Bean
    public Foo foo() {
        Foo foo = new Foo();
        foo.init();
        return foo;
    }

    // ...
}
                    
[Tip]Tip
Remember that because you are working directly in Java, you can do anything you like with your objects, and do not always need to rely on the container!

Tuesday, December 29, 2015

Difference between ResponseEntity and @ResponseBody?

Ref:- http://stackoverflow.com/questions/22725143/what-is-the-difference-between-responseentityt-and-responsebody


@RequestMapping(value = "/message")
@ResponseBody
public Message get() {
    return new Message(penguinCounter.incrementAndGet() + " penguin!");
}
At the same time I can use something like this
@RequestMapping(value = "/message")
ResponseEntity<Message> get() {
    Message message = new Message(penguinCounter.incrementAndGet() + " penguin!");
    return new ResponseEntity<Message>(message, HttpStatus.OK);
}
What is the difference betweet this two approaches?

ResponseEntity will give you some added flexibility in defining arbitrary HTTP response headers. See the 4th constructor here:
ResponseEntity(T body, MultiValueMap<String,String> headers, HttpStatus statusCode) 
A List of possible HTTP response headers is available here:
Some commonly-used ones are Status, Content-Type and Cache-Control.
If you don't need that, using @ResponseBody will be a tiny bit more concise.

Spring MVC @RequestBody @ResponseBody Example

Ref:- http://websystique.com/springmvc/spring-mvc-requestbody-responsebody-example/


@RequestBody and @ResponseBody annotations are used to bind the HTTP request/response body with a domain object in method parameter or return type. Behind the scenes, these annotation uses HTTP Message converters to convert the body of HTTP request/response to domain objects.


@RequestBody

If a method parameter is annotated with @RequestBody, Spring will bind the incoming HTTP request body(for the URL mentioned in @RequestMapping for that method) to that parameter. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the HTTP request body into domain object [deserialize request body to domain object], based on Accept header present in request.
  • The Accept header is used by HTTP clients [browsers] to tell the server what content types they’ll accept.
  • The server sends back the response, which will include a Content-Type header telling the client what the content type of the returned content actually is. In case of POST or PUT request, browsers do send data in request, so they actually send content-type as well.
Take this method for example:
@RequestMapping(value="/user/create", method=RequestMethod.POST)
public ResponseEntity<Void> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder){
    System.out.println("Creating User "+user.getName());
     
    if(userService.isUserExist(user)){
        System.out.println("A User with name "+user.getName()+" already exist");
        return new ResponseEntity<Void>(HttpStatus.CONFLICT);
    }
 
    userService.saveUser(user);
     
    HttpHeaders headers = new HttpHeaders();
    headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri());
    return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
This is the controller method to handle typical HTTP Post request [for URL /user/create]. In a pure REST oriented approach, this controller method creates a user, and returns the HTTP 201[CREATED] along with a LocationHeader containing the locations of newly created user [/app-address/user/1 e.g].
Now back to our original discussion, HTTP Post request body contains the detail of user to be created. When a client sends a request [/user/create] to create a user, it will be intercepted in this method. Method parameter user is marked with @RequestBody annotation. Thanks to this annotation, Spring will try to bind the request body [which can be JSON/XML/Other] to user object[ Means crating a new user object with the details found in the request body like user name,age etc..], based on Content-Type header in Http request.
But Spring need help to convert the request body into user object. It needs a converter which can convert the data in HTTP request body [which can be JSON/XML/Other] into user object.
Spring provides out-of-box many default HttpMessageConverters, which will be used for conversion, depending on presence of certain library in project classpath.
For example, if the Content-Type in request Header was one of application/json or application/xml , that means the POST body contains json or XML[Popular formats], and if Jackson library is found in your classpath, Spring will delegate the conversion to MappingJackson2HttpMessageConverter [for json] or MappingJackson2XmlHttpMessageConverter [for xml].
To declare a dependency to Jackson library (jackson-databind) include following dependency in your pom.xml
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>
ResponseEntity (used in above example) represents the entire HTTP response. Good thing about it is that you can control anything that goes into it. You can specify status code, headers, and body. Next post goes into details of it with a fully working example.

@ResponseBody

If a method is annotated with @ResponseBody, Spring will bind the return value to outgoing HTTP response body. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the return value to HTTP response body [serialize the object to response body], based on Content-Type present in request HTTP header.
Take this method for example:
@RequestMapping(value = "/user/all", method = RequestMethod.GET)
public @ResponseBody List<User> listAllUsers() {
    return userService.findAllUsers();
}
This is the controller method to handle typical HTTP GET request [for URL /user/all] to retrieve all users. In this case, Spring will convert the user list into appropriate format [JSON/XML/Other] using available converters, based on content type.
NOTE : As from Spring 4, @RestController is the preferred way to achieve the same functionality earlier provided by @ResponseBody. Under the hood, @RestController is @Controller+@ResponseBody, and it avoids the need of prefixing every method with @ResponseBody. Next post goes into details with a full working example.

Default HttpMessageConverters

Spring provides out of box following Http message converters which implements HttpMessageConverter interface [Credit : Spring Reference].

  • StringHttpMessageConverter
    An HttpMessageConverter implementation that can read and write Strings from the HTTP request and response. By default, this converter supports all text media types ( text/*), and writes with a Content-Type of text/plain.
  • FormHttpMessageConverter
    An HttpMessageConverter implementation that can read and write form data from the HTTP request and response. By default, this converter reads and writes the media type application/x-www-form-urlencoded. Form data is read from and written into a MultiValueMap.
  • ByteArrayHttpMessageConverter
    An HttpMessageConverter implementation that can read and write byte arrays from the HTTP request and response. By default, this converter supports all media types ( */*), and writes with a Content-Type of application/octet-stream. This can be overridden by setting the supportedMediaTypes property, and overriding getContentType(byte[]).
  • MarshallingHttpMessageConverter
    An HttpMessageConverter implementation that can read and write XML using Spring’s Marshaller and Unmarshaller abstractions from the org.springframework.oxm package. This converter requires a Marshaller and Unmarshaller before it can be used. These can be injected via constructor or bean properties. By default this converter supports ( text/xml) and ( application/xml).
  • MappingJackson2HttpMessageConverter
    An HttpMessageConverter implementation that can read and write JSON using Jackson’s ObjectMapper. JSON mapping can be customized as needed through the use of Jackson’s provided annotations. When further control is needed, a custom ObjectMapper can be injected through the ObjectMapper property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports ( application/json).
  • MappingJackson2XmlHttpMessageConverter
    An HttpMessageConverter implementation that can read and write XML using Jackson XML extension’s XmlMapper. XML mapping can be customized as needed through the use of JAXB or Jackson’s provided annotations. When further control is needed, a custom XmlMapper can be injected through the ObjectMapper property for cases where custom XML serializers/deserializers need to be provided for specific types. By default this converter supports ( application/xml).
  • SourceHttpMessageConverter
    An HttpMessageConverter implementation that can read and write javax.xml.transform.Source from the HTTP request and response. Only DOMSource, SAXSource, and StreamSource are supported. By default, this converter supports ( text/xml) and ( application/xml).
  • BufferedImageHttpMessageConverter
    An HttpMessageConverter implementation that can read and write java.awt.image.BufferedImage from the HTTP request and response. This converter reads and writes the media type supported by the Java I/O API.

Custom HttpMessageConverters

Most of the time, the default converters provided by Spring are enough. But if you need some custom behavior, you can roll out your own implementaion.
For instance, in above example, MappingJackson2HttpMessageConverter was used to handle JSON content. By default, the Jackson ObjectMapper supplied with this converter fails if there are missing properties in your JSON or domain object. It simply fails to convert. You can override this behavior by telling object mapper not to fail on missing properties, as shown below:
package com.websystique.springmvc.configuration;
 
import java.util.List;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.websystique.springmvc")
public class HelloWorldConfiguration extends WebMvcConfigurerAdapter{
     
     
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2HttpMessageConverter());
    }
     
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false));
        return converter;
    }
     
     
}
Here we have overridden extendMessageConverters method which provides a hook to add your own validator, wihtout skipping all existing validators.