Tuesday, 14 April 2020

Polymorphism

Polymorphism is the ability of an object to take on many forms. In OOP polymorphism is implemented by the Inheritance.

In Java, any class is polymorphic. Any class Is-A Object, meanwhile IS-A form of itself. At least, a class has two forms.

An abstract class, a superclass, or an interface, may have different forms due to their derivatives.  A derivative may have many different forms.

Virtual method refers to a method is a method that is overridden by a child class. Its implementation is determined by its run time implementation instance.





Saturday, 11 April 2020

Spring Mvc

Spring Web MVC

Spring web MVC is built on the servlet API and has been included in the Spring framework from the very beginning. The formal name, "Spring Web MVC", comes from the name of its source module(spring-webmvc), but it is more commonly known as "Spring MVC"

Servlet means Server Component. Here, the let means component.

Spring MVC follows the front controller pattern, which stands for the core of the framework. It accepts the Http requests from the clients and mapping them to the corresponding handlers(controllers),  which are also servlets.

DispatcherServlet

Spring MVC is designed around the front controller. It is a central servlet, i.e. dispatcher servlet, which provides a shared algorithm for request processing. However, actual works are performed by configurable delegators. This model is flexible and supports diverse workflows.

DispatcherServlet works like web.xml to mapping the request to its handler. Meaning that web.xml defines the mapping to locate the resource.


Traditionally, the developer needs to tell Spring container to bootstrap a servlet dispatcher by implements WebApplicationInitializer, where we may tell the container to instantiate a dispatcher servlet in the highest priority, meanwhile designating a specific WebApplicationContext, for instance, an AnnotationConfigWebApplicatoinContext. WebApplicationInitializer implementations are detected automatically, so you may package them within the application as you see fit. 

 public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
      XmlWebApplicationContext appContext = new XmlWebApplicationContext();
      appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

      ServletRegistration.Dynamic dispatcher =
        container.addServlet("dispatcher", new DispatcherServlet(appContext));
      dispatcher.setLoadOnStartup(1);
      dispatcher.addMapping("/");
    }

 }

In the above, WEB-INF/web.xml was replaced with code in the form of a WebApplicationInitializer, but the actual dispatcher-config.xml Spring configuration remained XML-based. This can be configured in a 100% code-based approach. 

 public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
      // Create the 'root' Spring application context
      AnnotationConfigWebApplicationContext rootContext =
        new AnnotationConfigWebApplicationContext();
      rootContext.register(AppConfig.class);

      // Manage the lifecycle of the root application context
      container.addListener(new ContextLoaderListener(rootContext));

      // Create the dispatcher servlet's Spring application context
      AnnotationConfigWebApplicationContext dispatcherContext =
        new AnnotationConfigWebApplicationContext();
      dispatcherContext.register(DispatcherConfig.class);

      // Register and map the dispatcher servlet
      ServletRegistration.Dynamic dispatcher =
        container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
      dispatcher.setLoadOnStartup(1);
      dispatcher.addMapping("/");
    }

 }

In the Spring boot, the dispatcher servlet doesn't need to be initialized but auto-generated by the Spring container.

Whatever the ApplicationConfig is required, it extends from WebMvcConfiguartionSupport, which implements ApplicationContextAware and ServletContextAware. Because the Aware interface, Application context will transfer back its instance to the WebAMvcConfigurationSupport. This is the main class providing the configuration behind the MVC java config. It is typically imported by adding @EnableWebMvc to an application @Configuation class.

Within ApplicationConfig, we need to define InternalResourceViewResolver, which declares ①viewClass=org.thymeleaf.spring5.view;②prefix=/resource/templates/ ;③ suffix =.html
They are all resources but located inside the project. That is why it is called Internal resources. The view class is dependent on which view technique is applied in the project; the prefix is put before the logic view name, and the suffix is put after the logic view name; so that they together form a directory tree.

InternalResourceViewResolver is the most popular view-resolver, but there are other variants.

Special bean types:

  • HandlerMapping: maps request to the handler.
  • HandlerAdapter: invokes a handler.
  • HandlerExceptionResolver: helps with exception handling.
  • ViewResolver: helps resolve views.
  • LocaleResolver: helps for l10n and i18n support. 
  • ThemeResolver: helps with stylized look and feel

Java-Based config:

We can now do completely in Java what used to be done in web.xml and Spring bean definition XML files.
  • Web application initializer
  • Root application context configuration
  • Dispatcher no.1 config: /main/*
  • Dispatcher no.2 config:/api/*

Controller

Controller Types:  @Controller and @RestController
@RestController only return @ResponseBody; but@Controller returns view(a logical string) and model.

Controller methods decorated by @RestMapping are handlers, which response the request from the clients.

Request mapping by:

  • URI pattern with @PathVariable
  • @RequestParameter and parameter condition
  • @ModelAttribute: binding form fields to the java POJO attributes 

Method input arguments:


25 supported

Method return values:

15 supported


Data Binding

Collecting data from view fields and binding them into java object, or in another way around, the java data model that is fetched from the controller, and then presented on the view (Html and JSP page)

From a view to a controller:

@ModelAttributes can be used at the method level or method parameter level.

When @ModelAttributes used at the method level. it is always called before any request handler(controller method decorated by a request mapping); meaning that, any model required has to be created before any request handler that can be carried out. This is used to instantiate models and giving them default values.

When @ModelAtrtributes used at the method parameter level, a form of a view can be bound into a java POJO model.

From controller to view: 

The model can supply attributes used for rendering views. To provide a view with usable data, we simply add this data to its Model object. It is used as a Map, storing the data with a key. The Model can be directly injected from the controller method argument.

Data Validation:

Data could be polluted in the views as reaching the controllers. so it needs to be validated.

Spring validator interface for application-specific objects.
JSR 380(javax.validation) bean validation API is the standard. It goes well with Spring 5.1.

Using annotations to add validation rules on java bean attributes. Then the Spring framework will do validation for us.

Using annotation @Valid to Enable validation in the Controller method argument. The validation result is contained a BindingResult parameter, which must be declared immediately after the validated target.

Data Converter

For Http requests, string-based values are extracted from the request including request parameters, path variables, request headers, and cookie values. They may need to be converted to the target type of the method parameter or field they are expected to. 

method parameters and type conversion

Binder methods:

Data transferred from the view normally in strings. @ModelAttribute can do field-to-attribute binding, mapping a string to string. In a case, binding a string to a specific java type, we have to declare a binder-method, which is used to register an object conversion or formating within a controller or globally across a group of controllers.

@InitBinderpublic void initBinder(WebDataBinder binder){
    binder.registerCustomEditor(Date.class, "dateOfBirth",   
    new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));}

@InitBinder method  is applied to the request parameter data, URI variables, and form beans
customizing data binding with @InitBinder
  • Bind request parameters(that is, form or query data) to an object(model)
  • Convert String-based request values(request parameters, path variables, headers, cookies, and others) to the target type of controller method arguments.
  • Format model object values as String values when rendering HTML forms.

Exception Handling 

  • Handled by DispatcherServlet
  • Delegates to handlerExceptionResolver beans
  • What does exception handling mean in an application

Implementations for exception handling:

  • ExceptionHandlerExceptionResolver: define exception handler methods in controllers
  • SimpleMappingExceptionResolver: map each exception class with an error page
  • DefaultHandlerExceptionResolver: default which maps exceptions to error codes
  • ResponseStatusExceptionResolver: resloves customer exceptions using @ResponseStatus

Handling exception locally in a controller scope.
 @ExceptionHandler modifies a method that should be invoked to handle an exception.

@ExceptionHandler({FileSystemException.class, RemoteException.class}) public ResponseEntity handle(IOException ex) { // ... }



Handling exception globally in a controller advice class.
Applying globally and across all @RequestMapping methods when defined with an @ControllerAdvice class or @RestContollerAdvice.

Annotating Business Exceptions with @ResponseStatus
A business exception can be annotated with @ResponseStatus. When the exception is raised, the ResponseStatusExceptionResolver handles it by setting the status of the response accordingly. By default, the DispatherServlet registers the ResponseStatusExceptionResolver and it is available for use.


Controller advice:

It is an aspect implementation relating to common concerns of controllers. If applying @ExceptionHandler, @ModelAttribute, and @InitBinder globally across all controllers, then you need to declare then within the class decorated with  @ControllerAdvice or @RestControllerAdvice.

The controller advice class is applied on every request, every controller; meanwhile, it allows to specify certain types of controllers(@Controller or @RestController), only for certain packages,  or specific controllers. @ControllerAdvice(assignableTypes={A.class,B.class}). 

On startup, the infrastructure classes for @RequestMapping and @ExceptionHandler methods detect Spring beans annotated with @ControllerAdvice and then apply their methods at runtime. Global @ExceptionHandler methods (from a @ControllerAdvice) are applied after local ones (from the @Controller). By contrast, global @ModelAttribute and @InitBinder methods are applied before local ones.

Async Request Processing

The request may be blocked due to a heavy task, which takes a long time to process.  Async request processing use Thread-1 to response Http Request thread, subsequently it uses Thread-2, which is A task executor thread in a thread pool, to handle the blocking task. The controller returns Callable or DeferredResult. 

Set the Mvc async processing flag to be true, so as to enable the async processing. Spring boot enables async-request processing by default. So, we don't need concern about this.

Configuring async processing in web-mvc-configuration: ➊ declare async task executor bean; ❷ set task executor within the asyncSupportConfigurer.

@Override
protected void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) {
    asyncSupportConfigurer.setDefaultTimeout(10000);    
    asyncSupportConfigurer.setTaskExecutor(mvcAsyncTaskExecutor());}

@Bean
public AsyncTaskExecutor mvcAsyncTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();    
    threadPoolTaskExecutor.setThreadNamePrefix("hplusapp-thread-");    
    return threadPoolTaskExecutor;}


View Resolver

The view resolver provides a mapping between view names and actual views.  The controller returns a view name in a string. According to the name, view resolver picks up the view template from a pre-defined folder, and then return to the client as an HTTP response.

There are many types of view resolvers:

InternalResourceViewResolver is used to pick up the JSP template in a correct folder in the project.
this is used to map a view name to its JSPs.

Employing a properties file to resolve views, which is done by a ResourceBundleViewResolver.
Meaning that defining all view names and map it to the correct JSPs in a properties file.

XmlViewResolver: implementation of ViewResolver that accepts a configuration file written in XML with the same DTD as Spring's XML bean factories.


VelocityViewResolver/FreeMarkerViewResolver
Convenient subclass of UrlBasedViewResolver that supports FreeMarkerView and custom subclasses of them.


Interceptor 

The concept of interceptions in Spring MVC is very similar to the filter components in the Servlet JSP API, which is used for pre- and post-processing of the request.


Built-in and customer interceptors

  • ThemChangeTnterceptor
  • LocalChangeInterceptor
  • Custom interceptors should extend HandlerInterceptorAdaper

Custom interceptors need to be registered in WebConfig class that implements
WebMvcConfigurerSupport

@Overrideprotected void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/*");    
    registry.addInterceptor(new ThemeChangeInterceptor());}

Session

A session may link several controllers.

@SessoinAttributes (used in class level)


Themes 

An application may have different themes. A theme stands for a different feel and a look of the view, which is defined by different CSS, images, icon ket, and font kit etc.

Define theme using org.springframework.ui.context.ThemeSource.
The default implementation is ResourceBundleThemeSource.
ThemeResolver decides which theme to use

  • CookieThemeResolver
  • SessionThemeResolver
  • FixedThemeResolver

Create theme properties file under the resource folder.
In ApplicationConfig, register ThemChangeInterceptor and creating bean ThemeResolver.
Used to refer themed keys from .properties file on the JSP. 


L10n and i18n 

Problem: common label or message may be fetched from a central place. Language may be presented differently in different countries.

LocaleResolver into play
Default implementation: AcceptHeaderLocaleResolver
Add message properties files for different locales on the classpath.


In spring boot defines messages-langShortName.properties
language short name is here i8n code 
fx: for Swedish, its short name is 'sv', and then the name for 'properties' file should be
messages-sv.properties


Creating message property files, key-value standing for the same label but different languages.
Note:
In IntelliJ, finding File Encoding file,  making sure default property file encoding is UTF-8, and also

including the 'Global encoding' and 'Project encoding'.



Chrome: settings: language. order preference of language


LocalResolver and CookieLocaleInterceptor
default key = 'locale'

Rest Controller

Access resource on the web; return data (ResponseEntity); MVC controller return view name;


Injecting Custom Arguments

When using Spring MVC you can add certain arguments to your controllers and the framework injects those arguments for you, fx: HttpServletRequest, Model, Locale, OutputStream etc.

Spring MVC provides us with an interface designed to allow us to inject parameters to our controller methods: HandlerMethodArgumentResolver.

Injecting custom method arguments
Inject your custom method argument in Spring MVC using HandlerMethodArgumentResolver

Can Jackson Deserialize Java Time ZonedDateTime

Yes, but must include JSR310. Thus ZonedDateTime can be deserialized directly from JSON response to POJO field. <dependency> <g...