Spring MVC 5 & Tomcat 9 - Unable to render the model attribute in the JSP [duplicate] - spring

This question already has answers here:
EL expressions not evaluated in JSP
(5 answers)
Closed 5 years ago.
I want to pass the model attribute to the JSP file and print it using the appropriate JSTL tags. When I call the /home, all I see is the tag I used to be placeholder (${name}) for the attribute; not the value I have set.
Here is my controller:
#Controller
#RequestMapping(value = "/*")
public class MainController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
public void home(Model model) {
model.addAttribute("name", "John");
}
}
The WebConfig class which implements WebMvcConfigurer
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.tk"})
public class WebConfig implements WebMvcConfigurer {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
WebAppInitializer class
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcherServlet.setLoadOnStartup(1);
dispatcherServlet.addMapping("/");
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
servletContext.addFilter("characterEncodingFilter", characterEncodingFilter).addMappingForUrlPatterns(null, false, "/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.tk.spring5App.config");
return context;
}
}
home.jsp file content:
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<body>
<h1><c:out value="${name}"/></h1>
</body>
</html>
And finally here is my pom.xml file:
<properties>
<java.version>1.8</java.version>
<spring.framework.version>5.0.3.RELEASE</spring.framework.version>
</properties>
<dependencies>
<!-- **********************************************************************
** SPRING DEPENDENCIES **
********************************************************************** -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<!--javax.servlet-api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<!--<scope>runtime</scope>-->
</dependency>
<!-- JSP Dependency -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<!-- JSTL Dependency -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--javax.xml-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
The web app is hosted on Apache Tomcat 9.0.4.

You probably have a (possible empty) web.xml with a version of 2.4 or lower in there. With that version evaluating EL expressions is disabled by default and as such expressions will show up as regular text.
Now you have 2 options either switch to a newer version 2.5
<web-app
version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
or remove the web.xml altogether relying only on annotations. Beware that not everything can be configured through annotations as you can in the web.xml or with web-fragment.xml if you need those configuration options (like <distributable />, extensive session configuration etc.) you still need an XML configuration (but just make sure it has a proper version).

Related

Form validation does not work in Spring Mvc Application

I have a Spring Mvc Application using Spring 5.2.8.RELEASE, which is deployed in a Tomcat 9.0.37 instance.
The dependencies section of my pom.xml is the following:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
<type>maven-plugin</type>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.1.5.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
My WebConfig class (which is returned in the getServletConfigClasses()) is:
#Configuration
#EnableWebMvc
#ComponentScan({"com.example.myapp.web", "com.example.myapp.data"})
public class WebConfig implements WebMvcConfigurer {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
I have the following bean that contains some validation constraints:
public class User {
private Long id;
#NotBlank
#Size(min = 5, max = 16)
private String firstName;
...
}
I have a JSP file for registering a new user:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<%# page session="false" %>
<html>
<head>
<title>User</title>
</head>
<body>
<h1>Register</h1>
<sf:form method="POST" modelAttribute="user">
First Name: <sf:input path="firstName"/><br/>
<!-- other fields -->
<input type="submit" value="Register"/>
</sf:form>
</body>
</html>
The controller that processes the request is the following:
#Controller
#RequestMapping("/user")
public class UserController {
// ...
#RequestMapping(value = "/register", method = POST)
public String processRegistration(#Valid User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "registerForm";
}
userRepository.save(user);
return "redirect:/user/" + user.getUsername();
}
// ...
}
The validation doesn't get triggered whenever I click the "Register" button in the browser.
However, when I invoke the method from a unit test, the validation is performed as expected (the test below fails because the redirection is not performed):
public class UserControllerTest {
#Test
public void shouldProcessRegistration() throws Exception {
UserRepository mockRepository = mock(UserRepository.class);
User unsaved = new User("John", "Doe", "jdoe", "pass");
User saved = new User(1L, "John", "Doe", "jdoe", "pass");
when(mockRepository.save(unsaved)).thenReturn(saved);
UserController controller = new UserController(mockRepository);
MockMvc mockMvc = standaloneSetup(controller).build();
mockMvc.perform(post("/user/register")
.param("firstName", "John")
.param("lastName", "Doe")
.param("username", "jdoe")
.param("password", "pass"))
.andExpect(redirectedUrl("/user/jdoe"));
verify(mockRepository, atLeastOnce()).save(unsaved);
}
}
UserController is in the web package, WebConfig in the config package and User in the package above these two (com.example.myapp).
Anyone has any idea what am I doing wrong?
I have read all related questions on this problem, but wasn't able to find any solution for my problem.
You answered your question.
Unit Test works and your form submit doesn't mean Your Data is not been set when you submit Form
Try this
#RequestMapping(value = "/register", method = POST)
public String processRegistration(#Valid #ModelAttribute("user") User user, BindingResult bindingResult) {
If the above doesn't work try adding a log to see if the value is been added to User Object.
I eventually managed to figure it out.
It was not a code problem, but a project configuration one.
After adding some dependencies in the pom.xml (namely hibernate-validator and hibernate-validator-annotation-processor), the corresponding artifacts were not automatically added in the output directory in WEB-INF/lib by IntelliJ IDEA.
I had to add these libraries manually: https://imgur.com/a/WRkD56F.
After doing so, the validation works as expected.

why i am getting nullpointerexception in JSP page for Spring DAO methods?

here, whenever I trying to access or call the DAO method (which is written in #Repository class) in the JSP page in My spring MVC Project using Hibernate, it showing NullPointerException.
it works fine when I accessing this method in Controller class, it just throwing an exception in the JSP page.
and here expection i am getting,
SEVERE: Servlet.service() for servlet [jsp] threw exception
java.lang.NullPointerException
at com.lms.service.BookDetailsServiceImpl.getBookStatusForLibrarianById(BookDetailsServiceImpl.java:62)
here is my code,
in pom.xml,
<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.libmansystem</groupId>
<artifactId>LibraryManagementSystems</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>LibraryManagementSystems Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<springframework.version>5.0.2.RELEASE</springframework.version>
<springsecurity.version>5.0.0.RELEASE</springsecurity.version>
<hibernate.version>5.4.14.Final</hibernate.version>
<mysql.connector.version>8.0.20</mysql.connector.version>
<c3po.version>0.9.5.5</c3po.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring MVC support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring ORM -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Hibernate Core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Add MySQL and C3P0 support -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3po.version}</version>
</dependency>
<!-- Servlet, JSP and JSTL support -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>LibraryManagementSystems</finalName>
<pluginManagement>
<plugins>
<plugin>
<!-- Add maven co-ordinates for : maven-war-plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
entity class,
#Entity
#Table(name = "book_status_forlibrarian")
public class BookStatusForLibrarian {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "s_id")
private Integer id;
#Column(name = "status")
private String status;
public BookStatusForLibrarian() {
}
public BookStatusForLibrarian(Integer id, String status) {
this.id = id;
this.status = status;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#Override
public String toString() {
return "BookStatusForLibrarian [id=" + id + ", status=" + status + "]";
}
}
Dao interface and class,
public interface BookDetailsDAO {
public BookStatusForLibrarian getBookStatusForLibrarianById(int statusId);
}
#Repository
public class BookDetailsDAOImpl implements BookDetailsDAO{
private SessionFactory sessionFactory;
#Autowired
public BookDetailsDAOImpl(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public BookDetailsDAOImpl()
{
}
#Override
public BookStatusForLibrarian getBookStatusForLibrarianById(int statusId) {
Session theSession = sessionFactory.getCurrentSession();
BookStatusForLibrarian theBookStatusForLibrarian = theSession.get(BookStatusForLibrarian.class, statusId);
return theBookStatusForLibrarian;
}
}
my service interface and class,
public interface BookDetailsService {
public BookStatusForLibrarian getBookStatusForLibrarianById(int statusId);
}
#Service
public class BookDetailsServiceImpl implements BookDetailsService {
#Autowired
BookDetailsDAO theBookDetailsDAO;
#Override
#Transactional
public BookStatusForLibrarian getBookStatusForLibrarianById(int statusId) {
System.out.println("inside service ");
return theBookDetailsDAO.getBookStatusForLibrarianById(statusId);
}
}
my controller,
#Controller
public class HomePageController {
#GetMapping("/homepage")
public String getHomePage()
{
return "homepage";
}
}
in my JSP page I am getting exception,
/WEB-INF/view/homepage.jsp,
<%#page import="com.lms.service.NonServiceMethod"%>
<%#page import="com.lms.dao.BookDetailsDAOImpl"%>
<%#page import="com.lms.service.BookDetailsServiceImpl"%>
<%#page import="com.lms.service.BookDetailsService"%>
<%#page import="com.lms.entity.BookStatusForLibrarian"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# page isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Show All Book</title>
</head>
<body>
<%
System.out.println("getting exception while calling Spring DAO method (which is written in #Repository class) in JSP page");
BookDetailsServiceImpl theBookDetailsService = new BookDetailsServiceImpl();
BookStatusForLibrarian getBookStatus= theBookDetailsService.getBookStatusForLibrarianById(3);
%>
</body>
</html>
and here expection i am getting,
SEVERE: Servlet.service() for servlet [jsp] threw exception
java.lang.NullPointerException
at com.lms.service.BookDetailsServiceImpl.getBookStatusForLibrarianById(BookDetailsServiceImpl.java:62)
please help me.
If you create the service in the JSP, it is not a Spring bean. There is no dependency injection done by Spring, you DAO is not injected in your service (NullPointerException). The correct way to pass the model (BookStatusForLibrarian) into the view (JSP) is to use the Controller.
#Controller
public class HomePageController {
#Autowired
BookDetailsService bookDetailsService;
#GetMapping("/homepage")
public String getHomePage(Model model) {
BookStatusForLibrarian bookStatus = bookDetailsService.getBookStatusForLibrarianById(3);
model.addAttribute("bookStatus", bookStatus);
return "homepage";
}
}
Then you can use bookStatus directly in the JSP without <% %> just like this: ${bookStatus.id}

How return MTOM in Spring BOOT WS

I have a problem with my Spring Boot Soap Server, im using Spring WS, i have to return my files in attachments, i return a Datahandler to the listtype created by Jaxb, but i see in the response in soap ui, attachments 0, and return me the files in base64.
I dont know how to do this.
Can you help me.
Thanks so much.
My Configuration Bean is:
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/services/*");
}
#Bean(name = "students")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("StudentPort");
wsdl11Definition.setLocationUri("/ws/services/test");
wsdl11Definition.setTargetNamespace("http://www.example.org/demo/");
wsdl11Definition.setSchema(countriesSchema);
Properties props = new Properties();
props.put("getDemo", "http://www.example.org/demo/getDemoRequest");
wsdl11Definition.setSoapActions(props);
return wsdl11Definition;
}
#Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource("/it/xsd/demo.xsd"));
}
My endpoint have only these annotations:
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getDemoRequest")
#ResponsePayload
In my demo.xsd, i setted the fileType in
<element name="fileType" type="base64Binary" maxOccurs="unbounded" xmime:expectedContentTypes="application/octet-stream">
I havent xml configuration for now, i would like dont use any xml if it is not necessary in perfect style of Spring Boot.
Thanks so much.
UP:
My code to try enable MTOM.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor;
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
import java.util.List;
#Configuration
public class MTOMEnable extends WsConfigurerAdapter {
#Override
public void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(methodProcessor());
}
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(GetStudentsResponse.class);
marshaller.setMtomEnabled(true);
return marshaller;
}
#Bean
public MarshallingPayloadMethodProcessor methodProcessor() {
return new MarshallingPayloadMethodProcessor(marshaller());
}
}
POM
<dependencies>
<!-- SOAP DEPENDENCIES-->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.2</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.2</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.sun.org.apache.xml.internal</groupId>
<artifactId>resolver</artifactId>
<version>20050927</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
<!--<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.2.0.jre8</version>
<scope>runtime</scope>
</dependency>-->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.4.0-b180830.0438</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version> <!-- makesure you put a correct version here -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
The problem is that the DefaultMethodEndpointAdapter bean adds our MTOM-enabled JAXB marshaller/unmarshaller to the END of the handlers' list. The trick is to override the DefaultMethodEndpointAdapter bean and put them FIRST. This way you don't even need to override the addArgumentResolvers().
The following is Kotlin but should be easy enough to convert to plain Java.
#Bean
override fun defaultMethodEndpointAdapter() = object: DefaultMethodEndpointAdapter() {
override fun initDefaultStrategies() {
super.initDefaultStrategies()
methodArgumentResolvers.add(0, methodProcessor()) // needs to be FIRST in list
methodReturnValueHandlers.add(0, methodProcessor()) // needs to be FIRST in list
}
}
You also need to make sure the relevant #RequestPayload and return params are JAXBELement<...>

Spring Boot MVC ViewResolver not working, not mapping to internal folder location

I am developing a spring boot mvc using Spring boot 1.5.6, Java 8. I am trying to use InternalResourceViewResolver for JSP page redirects/path. But it is unable to resolve the path. Could you please let me know what's wrong. Below are the codes
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Resource
private Environment env;
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
registry.addViewController("/registration.html");
registry.addViewController("/logout.html");
registry.addViewController("/home.html").setViewName("home");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resource/**").addResourceLocations("/static/");
}
// beans
#Bean
public ViewResolver viewResolver() {
final InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/ui/");
bean.setSuffix(".jsp");
return bean;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(viewResolver());
}
}
application.properties
server.context-path=/xxxx
spring.profiles.active=dev
logging.level.org.springframework.web=TRACE
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Below is the project structure
There is another approach in the latest spring version much simpler
Add the below in Application Properties
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
Also make sure your Project Structure is like this src/main/webapp/WEB-INF/jsp
and under this your files home.jsp login.jsp
In your ViewResolver, change bean.setPrefix("/ui/") to bean.setPrefix("/WEB-INF/ui/") like this:
#Bean
public ViewResolver viewResolver() {
final InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/ui/");
bean.setSuffix(".jsp");
return bean;
}

CSS and JS file not loading while deploying war file on apache tomcat

was using the spring-boot-starter-web-mvc for initial development.When I deploy the war file on the server it is not loading css and js files, but when I run the same code using spring boot, it is working fine. Below is the directory structure and configuration loading the js and css file. Can anyone please let me know how to what is the problem ? Using only java based configuration for project. I have referred 8.1.1 in the doc before deploying the project and used the same pom file configuration as below.
Configuration file -
public class ViewWebAppConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// configuration for assets/ static files
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource rb = new ResourceBundleMessageSource();
rb.setBasenames(new String[] { "validation" });
return rb;
}
}
pom.xml file
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<log4j.version>2.7</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- Dependency for rendering jsp pages -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>tomcat</groupId>
<artifactId>jasper-compiler</artifactId>
<version>5.5.23</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>tomcat</groupId>
<artifactId>jasper-runtime</artifactId>
<version>5.5.23</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>tomcat</groupId>
<artifactId>jasper-compiler-jdt</artifactId>
<version>5.5.23</version>
<scope>provided</scope>
</dependency>
<!-- Dependency for rendering jsp pages -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
</dependencies>
Loading the js and css using spring-tags as below -
<%#taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:url value="/resources/assets/js/custom.min.js" var="customJS" />
<script src="${customJS}"></script>
<link href="${customFieldAgent}" rel="stylesheet"/>
<spring:url value="/resources/assets/css/customfieldAgent.css" var="customFieldAgent" />
Below is the server log -
17:03:10.014 [http-nio-8080-exec-7] DEBUG
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
- Did not find handler method for [/${starrrJS}] 17:03:10.014 [http-nio-8080-exec-7] WARN
org.springframework.web.servlet.PageNotFound - No mapping found for
HTTP request with URI [/ui/$%7BstarrrJS%7D] in DispatcherServlet with
name 'dispatcher' 17:03:10.014 [http-nio-8080-exec-7] DEBUG
org.springframework.web.servlet.DispatcherServlet - Successfully
completed request 17:03:10.018 [http-nio-8080-exec-4] DEBUG
org.springframework.web.servlet.DispatcherServlet - DispatcherServlet
with name 'dispatcher' processing GET request for
[/ui/$%7BcustomJS%7D] 17:03:10.018 [http-nio-8080-exec-4] DEBUG
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
- Looking up handler method for path /${customJS} 17:03:10.019 [http-nio-8080-exec-4] DEBUG
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
- Did not find handler method for [/${customJS}] 17:03:10.019 [http-nio-8080-exec-4] WARN
org.springframework.web.servlet.PageNotFound - No mapping found for
HTTP request with URI [/ui/$%7BcustomJS%7D] in DispatcherServlet with
name 'dispatcher' 17:03:10.019 [http-nio-8080-exec-4] DEBUG
org.springframework.web.servlet.DispatcherServlet - Successfully
completed request
Try this way it is working for me.
Project Structure:
src/main/webapp/static/[css,js,images]
src/main/webapp/WEB-INF/views/[for all .jsp pages]
Configuration
#Configuration
#ComponentScan(basePackages = "parent package name where all packages reside")
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// when static resources are inside resources folder under WEB-INF
// registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/");
// when static resources are inside static folder under webapp
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
Let DispatcherServlet know how to pack things up...
import javax.servlet.Filter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ApplicationConfiguration.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
Now call these on view like...
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="<c:url value='/static/css/application.css' />" rel="stylesheet"></link>
</head>
Add this in your pom.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
Hope this will help you.
In my Spring Boot project,i tried to deploy as WAR file into TOMCAT,but it does not recognize the resource path,it throws 404 File not found error,But when i run as SpringBootApplication,it works properly,issue only when deploy as a WAR file into TOMCAT. so finally i revealed the issue now it works perfectly on my project structure
adding those lines into application.properties file
spring.resources.add-mappings=true
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/
i got from https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
it works perfectly...
for this js,images,css or from outside of the war file images or any file can be shown and also get access by using
this below line is common to two scenarios
spring.resources.add-mappings=true
For in the spring boot war file or any file of spring to get accessed or shown this u have to put in application.properties file or any property file
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/
For external access file or showing external files of images u may put as
spring.resources.static-locations=file:///C:/xxxxxxxxx/xxxxxxxxx
AS said vignesh R it was working great try it

Resources