Parsing JSON With Java 8 Without Dependencies

While working with JSON we often need to parse the JSON into an object, or Map, or List, or to a custom object as well.  To parse the JSON we have to use a dependency to process it easily.

But, starting with JDK 8u60+ the built-in Nashorn engine is capable to convert JSON content into java.util.Map or java.util.List. No external dependencies are required for parsing.

Here is an example with sample JSON. You can follow the below steps.

  1. Copy the below JSON into a file “test.json” and place it inside your java project.
{
	"page": "1",
	"per_page": 10,
	"total": 23,
	"total_pages": 3,
	"data": [
		{
			"competition": "UEFA Champions League",
			"year": 2014,
			"round": "GroupG",
			"team1": "Chelsea",
			"team2": "Schalke 04",
			"team1goals": "1",
			"team2goals": "1"
		},
		{
			"competition": "UEFA Champions League",
			"year": 2014,
			"round": "GroupG",
			"team1": "Chelsea",
			"team2": "NK Maribor",
			"team1goals": "6",
			"team2goals": "0"
		},
		{
			"competition": "UEFA Champions League",
			"year": 2014,
			"round": "GroupG",
			"team1": "Chelsea",
			"team2": "Sporting CP",
			"team1goals": "3",
			"team2goals": "1"
		},
		{
			"competition": "UEFA Champions League",
			"year": 2014,
			"round": "R16",
			"team1": "Chelsea",
			"team2": "Paris Saint-Germain",
			"team1goals": "1",
			"team2goals": "1"
		},
		{
			"competition": "English Premier League",
			"year": 2014,
			"round": "",
			"team1": "Chelsea",
			"team2": "Leicester City",
			"team1goals": "2",
			"team2goals": "0"
		},
		{
			"competition": "English Premier League",
			"year": 2014,
			"round": "",
			"team1": "Chelsea",
			"team2": "Swansea City",
			"team1goals": "4",
			"team2goals": "2"
		},
		{
			"competition": "English Premier League",
			"year": 2014,
			"round": "",
			"team1": "Chelsea",
			"team2": "Aston Villa",
			"team1goals": "3",
			"team2goals": "0"
		},
		{
			"competition": "English Premier League",
			"year": 2014,
			"round": "",
			"team1": "Chelsea",
			"team2": "Arsenal",
			"team1goals": "2",
			"team2goals": "0"
		},
		{
			"competition": "English Premier League",
			"year": 2014,
			"round": "",
			"team1": "Chelsea",
			"team2": "Queens Park Rangers",
			"team1goals": "2",
			"team2goals": "1"
		},
		{
			"competition": "English Premier League",
			"year": 2014,
			"round": "",
			"team1": "Chelsea",
			"team2": "West Bromwich Albion",
			"team1goals": "2",
			"team2goals": "0"
		}
	]
}

2. Create a class “JSONParser.java” and put the below code inside it.

package com.codersdesks.json;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.junit.Before;
import org.junit.Test;

public class JSONParser {
	
	private ScriptEngine scriptEngine;
	private String json;

	@Before
	public void setup() throws IOException {
		ScriptEngineManager sem = new ScriptEngineManager();
		this.scriptEngine = sem.getEngineByName("javascript");
		File file = new File("test.json");
		this.json = new String(Files.readAllBytes(file.toPath()));
	}

	@Test
	public void parse() throws ScriptException {
		String script = "Java.asJSONCompatible(" + this.json + ")";
		Object result = this.scriptEngine.eval(script);
		Map contents = (Map) result;
		
		contents.forEach((k,v) ->{
			System.out.println("Key => "+k +" value =>"+contents.get(k));
		});
		
		List data = (List) contents.get("data");
		data.forEach(d ->{
			Map matchDetail = (Map) d;
			matchDetail.forEach((k,v) ->{
				System.out.println("Key => "+k +" value =>"+matchDetail.get(k));
			});	
		});
	}

}

Run the Junit test and you can see the below output.

Key => page value =>1
Key => per_page value =>10
Key => total value =>23
Key => total_pages value =>3
Key => data value =>[[object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object]]
Key => competition value =>UEFA Champions League
Key => year value =>2014
Key => round value =>GroupG
Key => team1 value =>Chelsea
Key => team2 value =>Schalke 04
Key => team1goals value =>1
Key => team2goals value =>1
Key => competition value =>UEFA Champions League
Key => year value =>2014
Key => round value =>GroupG
Key => team1 value =>Chelsea
Key => team2 value =>NK Maribor
Key => team1goals value =>6
Key => team2goals value =>0
Key => competition value =>UEFA Champions League
Key => year value =>2014
Key => round value =>GroupG
Key => team1 value =>Chelsea
Key => team2 value =>Sporting CP
Key => team1goals value =>3
Key => team2goals value =>1
Key => competition value =>UEFA Champions League
Key => year value =>2014
Key => round value =>R16
Key => team1 value =>Chelsea
Key => team2 value =>Paris Saint-Germain
Key => team1goals value =>1
Key => team2goals value =>1
Key => competition value =>English Premier League
Key => year value =>2014
Key => round value =>
Key => team1 value =>Chelsea
Key => team2 value =>Leicester City
Key => team1goals value =>2
Key => team2goals value =>0
Key => competition value =>English Premier League
Key => year value =>2014
Key => round value =>
Key => team1 value =>Chelsea
Key => team2 value =>Swansea City
Key => team1goals value =>4
Key => team2goals value =>2
Key => competition value =>English Premier League
Key => year value =>2014
Key => round value =>
Key => team1 value =>Chelsea
Key => team2 value =>Aston Villa
Key => team1goals value =>3
Key => team2goals value =>0
Key => competition value =>English Premier League
Key => year value =>2014
Key => round value =>
Key => team1 value =>Chelsea
Key => team2 value =>Arsenal
Key => team1goals value =>2
Key => team2goals value =>0
Key => competition value =>English Premier League
Key => year value =>2014
Key => round value =>
Key => team1 value =>Chelsea
Key => team2 value =>Queens Park Rangers
Key => team1goals value =>2
Key => team2goals value =>1
Key => competition value =>English Premier League
Key => year value =>2014
Key => round value =>
Key => team1 value =>Chelsea
Key => team2 value =>West Bromwich Albion
Key => team1goals value =>2
Key => team2goals value =>0

You can also read about JSON Schema and How to use Jackson databind with JSON

For more information, you can refer to the official Nashorn extensions documentation.

Happy Learning !!

javax.el.PropertyNotFoundException: Property not found on type

Problem

While using JSTL for iterating a list of custom objects encountered the following exception.

<c:forEach items="{trendingItems}" var="trending">

2020-02-01 11:52:18 - Servlet.service() for servlet [jsp] threw exception
javax.el.PropertyNotFoundException: Property [itemName] not found on type [java.lang.String]
	at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:260) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:212) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at javax.el.BeanELResolver.property(BeanELResolver.java:347) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at javax.el.BeanELResolver.getValue(BeanELResolver.java:92) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:113) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.el.parser.AstValue.getValue(AstValue.java:169) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:701) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.jsp.WEB_002dINF.view.trending_002ditems_jsp._jspx_meth_c_005fforEach_005f3(trending_002ditems_jsp.java:744) ~[na:na]
	at org.apache.jsp.WEB_002dINF.view.trending_002ditems_jsp._jspService(trending_002ditems_jsp.java:285) ~[na:na]
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:170) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) [spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
2020-02-01 11:52:18 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [An exception occurred processing [/WEB-INF/view/trending-items.jsp] at line [152]

149: 		                                    <tbody>
150: 		                                    	<c:forEach items="trendingItems" var="trending">
151: 		                                    	<tr>
152: 		                                    		<td>${trending.itemName}</td>

Stacktrace:] with root cause
javax.el.PropertyNotFoundException: Property [itemName] not found on type [java.lang.String]
	at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:260) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:212) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at javax.el.BeanELResolver.property(BeanELResolver.java:347) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at javax.el.BeanELResolver.getValue(BeanELResolver.java:92) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:113) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.el.parser.AstValue.getValue(AstValue.java:169) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190) ~[tomcat-embed-el-9.0.16.jar:9.0.16]
	at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:701) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.jsp.WEB_002dINF.view.trending_002ditems_jsp._jspx_meth_c_005fforEach_005f3(trending_002ditems_jsp.java:744) ~[na:na]
	at org.apache.jsp.WEB_002dINF.view.trending_002ditems_jsp._jspService(trending_002ditems_jsp.java:285) ~[na:na]
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329) ~[tomcat-embed-jasper-9.0.16.jar:9.0.16]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:170) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.16.jar:9.0.16]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]

Finding

While going through the exception stack trace for a couple of times I found that I have missed the ‘${}’ symbol in for each item.

<c:forEach items="trendingItems" var="trending">
<tr>
<td>${trending.itemName}</td>

Solution

This correct syntax of c:forech will be:

<c:forEach items="${trendingItems}" var="trending">

Recommended Read

Java Exception in detail with example
How to create custom Java Exception?

Reference

JSTL

Happy Learning !!

com.fasterxml.jackson.databind.exc.MismatchedInputException

Problem:
Using jackson-databind-2.9.8.jar to deserialize JSON into List but hits the below exception.

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `web.dto.PersonDTO` out of START_ARRAY token.

Solution 1:

JsonMappingException: out of START_ARRAY token exception is thrown by Jackson object mapper as it’s expecting an Object {} whereas it found an Array [{}] in response. Make sure your JSON is a single object instead of an Objects Array.

Solution 2:
Your JSON is an Array of Objects and you are trying to map it into a List but missed to define type reference as List as shown below.

List persons = mapper.readValue(personJSON, new TypeReference() {});

The correct mapping would be as below:

List persons = mapper.readValue(personJSON, new TypeReference>() {});

Read more about Java exception

Happy Learning !!

HTTP Request Methods and specification

HTTP defines a set of request methods to specify the desired action to be performed for a given resource. These request methods are sometimes referred to as HTTP verbs. Each of them implements a different semantic, but some common features are shared by a group of them: e.g. a request method can be safe, idempotent, or cacheable.

Http Request Method

Use Request Methods to map CRUD (create, retrieve, update, delete) operations to HTTP requests.

Method DescriptionExample
GETGET is used to Retrieve information. GET requests must be safe and idempotent, meaning regardless of how many times it repeats with the same parameters, the results has to be same.Retrieve an Employee with an ID of 1:
GET /employee/1
POSTThe POST method is used to submit an entity to the specified resource, often used to create a new entity, but it can also be used to update an entity.Create a new Employee:
POST /addresses
PUTThe PUT method replaces all current representations of the target resource with the request payload and it is idempotent.
Idempotency is the main difference between PUT versus a POST request.
Modify the Employee with an ID 1:
PUT /addresses/1
DELETEThe DELETE method delete the specified resource. Delete an employee having ID 1:
DELETE /addresses/1
OPTIONSThe OPTIONS method is used to describe the communication options for the target resource.
PATCHThe PATCH method Update only the specified fields of an entity at a URI. A PATCH request is also idempotent.PATCH /addresses/1

Specifications
RFC 7231, section 4: Request methods Specifies GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE.

RFC 5789, section 2: Patch method Specifies PATCH.

Recommended Read
Rest Web Services

Happy Learning !!

Recommended books for programmers

1. Clean Code: A Handbook of Agile Software Craftsmanship
Even bad code can function. But if code isn’t clean, it can bring a development organization to its knees. Every year, countless hours and significant resources are lost because of poorly written code. But it doesn’t have to be that way.

Read this book and see the changes it will bring to the way your write code.

Courtesy: Clean Code

An Introduction to JAX RS Annotations

In This tutorial, we will learn about JAX RS annotations specified in JAX-RS specification. Each available annotation is used for a specific task. Let see the list of Available JAX-RS Annotations.

Annotation Package/Import statement Description
@GET import javax.ws.rs.GET; To retrieve a resource
@POST import javax.ws.rs.POST; To create a new resource
@PUT import javax.ws.rs.PUT; To change the state or update a resource
@DELETE import javax.ws.rs.DELETE; To remove or delete a resource
@HEAD import javax.ws.rs.HEAD; To receive the service header information
@Consumes import javax.ws.rs.Consumes; To define the kind of data service will accept to process
@Produces import javax.ws.rs.Produces; To define the kind of data service will produce after processing
@Path import javax.ws.rs.Path; To Define service URI
@PathParam import javax.ws.rs.PathParam; To extract URI path parameters from request URI
@QueryParam import javax.ws.rs.QueryParam; To extract query parameters from request URI
@FormParam import javax.ws.rs.FormParam; To receive post request form data directly by form filed name

Recommended Read

Rest Web Services
Principles of REST Web Services

REST Hello World Example using Jersey

REST Hello World Example:

In this tutorial, we will develop a simple REST Hello world example web service. Here are the prerequisites.

  1. Jersey-bundle 1.19.4
  2. Tomcat 7
  3. Eclipse IDE
  4. JDK 1.7

Maven Dependencies, you can get it from the Maven repository.

<dependency>
	<groupId>com.sun.jersey</groupId>
	<artifactId>jersey-bundle</artifactId>
	<version>1.19.4</version>
</dependency>

Add Servlet mapping in web.xml

<servlet>
	<servlet-name>jersey-serlvet</servlet-name>
	<servlet-class>
	com.sun.jersey.spi.container.servlet.ServletContainer
	</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>jersey-serlvet</servlet-name>
	<url-pattern>/service/*</url-pattern>
</servlet-mapping>

URL pattern “/service/*” means every service URI will start with /service followed by @Path annotation value.

Write HelloService.Java class and create a method helloWorld like.

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/hello")
public class HelloService {
   @GET
   public String helloWorld(){
     return "Hello World";
   }
}

After completing the above activities right click on Project, go to Run As, and click on 1 Run on Server. Once the server started successfully, open any web browser and type http://localhost:8181/RestDemo/service/hello and press enter. You will see the service response below.

Hello World Response

Notice port 8181, by default Tomcat, runs on port 8080, make sure you use the correct one. We are running it in 8181.

You can download the complete Hello World Example Source Code.

Recommended Read:

Rest Web Services
Principles of REST Web ServicesAccess restriction: The type ‘Resource’ is not API

Happy Learning !!

Principles of REST Web Services

REST Web Services

Although the concept of REST Web Services is written more the one and a half-decade ago, it has not been used much until recent times that the REST web services become so popular and everyone started using them. The major gain in its popularity and uses is because REST architecture offers many advantages over its counterpart. Let’s check out some of its key principles.

1. Resources:

As described in the earlier post everything in REST is a resource. The key to writing a REST resource is that it has to be in the form of the directory structure. Every time while developing a REST web service make sure you expose easily understood directory structure URIs. Resources have data associated with them.

Example of Resources

For example, if you want to expose user data through a REST web service, then you can provide user data in two form either individual user data or all users’ data. In that case, the URI should be like http://yourapplication/{api_version}/users/{user_id}. If the client wants all user data he can exclude user_id from your URI and if clients need specific user data they can pass the user_id.

i.e http://yourapplication/v.01/users – for all Users

http://yourapplication/v.01/users/123 – for User having user-id as 123

2. Representations:

Representations mean the response (JSON/XML) returned by the REST web service should represent data objects and their attributes. In JSON there are three types of data that exist.
A) Scalar (String, Number, Boolean, null) – scalar type has a single value.
B) Object – Object consists of an understood key: value pair ( also called its attributes). While the key is a String and the value can have an arbitrary type.
C) Array – Array contains an ordered list of arbitrary types, can also contain a list of Objects as well.

3. Messages:

The key while developing the REST web service is to use the appropriate HTTP verbs (methods). For example GET, POST, PUT, and DELETE. You can read more about HTTP methods here.

4. Stateless:

Stateless servers do not maintain any information about the client or the user. Each request is fully independent of the previous one. The user or client has to pass all the information in every request even if the server can identify the user based on any allocated id.

5. Media Type:

Mention the type of data the REST web service will consume and produce. In other words kind of data that web service will accept and return. The Accept and Content-Type request headers can be used to describe the content being sent or requested within an HTTP request. The client can set Accept to Application/JSON if the web service it is calling will return a response in JSON.

6. HTTP Status Code:

The status code describes the result of the HTTP request. Below is the list of status codes with their meaning.
A) 1XX – Informational
B) 2XX – Success
C) 3XX – Redirection
D) 4XX – Client Error
E) 5XX – Server Error

Recommended Read:

Rest Web Services
REST Hello World Example

Reference:

Representational state transfer

Happy Learning !!