Menu

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

Get requested page URL from request in Spring Boot

How to get the requested URL information in a Spring security project so that we can redirect the user to the secure or right page after successful login. On every request Spring security stores the following information in the session key "SPRING_SECURITY_SAVED_REQUEST". This way will help us to get the last requested URL or request from where a user started the authentication request that redirected the user to the login page.

SPRING_SECURITY_SAVED_REQUEST key spring boot-request-url
SPRING_SECURITY_SAVED_REQUEST

Below is the code snippet to get the requested url from the "SPRING_SECURITY_SAVED_REQUEST" key.

DefaultSavedRequest savedRequest = (DefaultSavedRequest)request.getSession()
        .getAttribute("SPRING_SECURITY_SAVED_REQUEST");
    	if(savedRequest != null) {
    		String previousPageUrl = savedRequest.getRedirectUrl();
    		
    	} 

This will helps us to redirect the users to the secure page after successful login. Thank you, hope this solves your problem.

Custom error page in spring boot web application

Spring provide an out-of-the-box "Whitelabel Error Page". When any error occurs in our Spring application this default error page will appear.

Which look like as below:

Spring default error page

How to disable the OOTB or whitelabel error page in Spring?

We can disable the default whitelabel error page, which is OOTB error page of Spring application by setting a property 'server.error.whitelabel.enabled' to false in application.properties property file.

server.error.whitelabel.enabled=false

How to create custom error page in Spring?

Spring provide a functional interface ErrorController to handle the errors. We need to create a controller class by implementing this interface ErrorController to handle the custom error and show different error message and pages to end users.

Since ErrorController is a functional interface, hence this interface contains only one method 'getErrorPath()'. In Spring 2.3.0 this method has been deprecated and since 2.3.0 we may use property 'server.error.path' to specify the error path. 

This(server.error.path) property we can set in our application.properties file.

server.error.path=/error

Now create a CustomErrorHandlerController class which will implement ErrorController interface. In this class we will create a @RequestMapping for path /error and render the request to our custom error page. Below is the sample code, here we have created customErrorPage() method which is mapped with /error path.

CustomErrorHandlerController.java

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CustomErrorHandlerController implements ErrorController{

	@Override
	public String getErrorPath() {
		return null;
	}
	
	@RequestMapping("/error")
    public String customErrorPage() {
        return "views/error";
    }
}

You may wondering why we have use the default method in this class which is returning null. This is because we have to provide the definition of all the method of an interface otherwise it will generate compile time error.

Now create a error.html page under views, which will appear when any error occur in the Spring application. 

error.html

<html>
  <title>Spring custom error page</title> 
 <body>
  <h1>Ooops!!</h1>
  <div>
  <h3>Something unexpected happened</h3>
  <p>If you are seeing this message frequently then, please report us. </p>

  <br />
  </div>
 </body>
</html>

We have done with changes now run the application and validate the error page functionality. Next time when system will generate any error then you will see this custom error page instead of whitelabel error page. You may also render to different error pages based on errors and their definition 

e.g. error code 404 render to 404-error.html page and 

error 400 render to 400-error.html page.

These all we can handle in customErrorPage method. We need to create an object of HttpServletRequest and check the status using if-else condition and return the respective error page. 


Hope this helps you!

References:

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

https://docs.spring.io/spring-boot/docs/current/api/index.html?org/springframework/boot/web/servlet/error/ErrorController.html 

How to change default port for Spring boot

Default port for Spring boot application is 8080, what if someone want to run their application other than port 8080 or other than default port. Where we need to put the port setting in project, so instead of default port 8080 Spring boot application start on port which we configure.

By Default Spring boot run on port 8080 and no where in your project you will find the port setting, if you just started a new Spring boot project. If you want to change the default port then you have to add the port setting in your project.

Where to put the port setting?

We need to add port setting in projects application.properties file. You will find this properties file under project directory > src > main > resources > application.properties

open application.properties file and add a new property server.port followed by port number. below is the example.
server.port = 8020

Consider defining a bean of type in your configuration

A compile-time error thrown by Spring application as following "Consider defining a bean of type 'org.sling.service.ServiceClass' in your configuration". This means we have created a class or interface and trying to use it as a service or bean, but your class or interface doesn't have the feature of bean. 
So, to fix this with a service class use annotation @Service [org.springframework.stereotype.Service] on top of your class declaration will fix this error.

How to set property of a bean from external source file using Spring framework

Today in this tutorial we are going to discuss how to set property of a bean from external source file using Spring framework.

As we already know Spring is a very powerful framework to inject the dependency at get the value at run time in the form of beans. But what happen if we don't have value for those beans in our ApplicationContext.xml file and we need to fetch value from some external file or data source and assign those values to beans. We will see these all in a sample example program.

Files used in this example:


  1. Apple.java
  2. myApp.properties
  3. AppContextRashid.xml
  4. ClassHer.java


First we will create a java POJO calss "Apple.java" in this class we will create two String variables and their getters and setters. Also we will create a method whoareyou() with return type String.
Below is the code:
package rashidtest;
public class Apple  {
String name1, desc1="not yet set";
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
public String whoareyou() {
String result= name1 + desc1;
if(desc1 == null) return name1;
else if(name1 == null) return desc1;
else return result;
}
}

Second we will create a property file which contains the value for name1 and desc1 variables. to do so we will create a file "myApp.properties" in a xmlBeans package in our source directory which have some values. below is the example file.

def-desc=I am a fruit and my color is Red.
def-name=Apple.

Third we will create a xml bean file "AppContextRashid.xml" in which we will to include namespace "xmlns:context="http://www.springframework.org/schema/context" to read the data from external source.

To read the external property or value from file we will provide the location in property placeholder. e.g. <context:property-placeholder location="xmlBeans/myApp.properties"/> 

Then in Bean property tag we will assign values from file to POJO class variables. To get the value from properties file we will write "${name of the property}". 
e.g. <property name="desc1" value="${def-desc}"></property> 
In the above statement we are fetching value for property "def-desc" from .property file and assigning its value to "desc1" variable in Apple class.

<?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:context="http://www.springframework.org/schema/context"
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-4.3.xsd">
<context:property-placeholder location="xmlBeans/myApp.properties"/> 
<bean id="apple" class="rashidtest.Apple">
<property name="desc1" value="${def-desc}"></property>
<property name="name1" value="${def-name}"></property>
</bean>
</beans>

Fourth and final we will create a implementer class which have main method, instance of ApplicationContext and inject the value from bean to class using setter injection. to achieve this we will create a java file "ClassHer.java". Below is the complete class.

package rashidtest;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClassHer {
public static void main(String[] args) {
ApplicationContext appContext=new ClassPathXmlApplicationContext("rashidtest/AppContextRashid.xml");
Apple apple=appContext.getBean("apple", Apple.class);
System.out.println("Apple class have property: " +apple.whoareyou());
}
}

Simple Spring project example

Create a implementation class ImplCode.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

public class ImplCode {

 public static void main(String[] args) {

  ApplicationContext appContext=new FileSystemXmlApplicationContext("AppContextBeanFile.xml");

  Fruit fruit=appContext.getBean("fruit", Fruit.class);

  Vegetable veg=(Vegetable) appContext.getBean("veg");

  System.out.println(fruit.whoareyou());

  System.out.println(veg.whoareyou());

 }

}

Create a bean class Vegetable.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package rashiddemo;

public class Vegetable {

 public String whoareyou() {

  String intro="I am vegetable!!";

  return intro;

 }

}

Create another bean class Fruit.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package rashiddemo;

public class Fruit {

 public String whoareyou() {

  String intro="I am fruit!";

  return intro;

 }

}

Create a AppContextBeanFile.xml and add your bean classes using bean tag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>

<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.xsd">

  <bean id="fruit" class="rashiddemo.Fruit"></bean>

 <bean id="veg" class="rashiddemo.Vegitable"></bean>

</beans>