Spring mvc jsp not rendering - spring

Getting started with Spring MVC, when I enter my page it loads the welcome.jsp as plain text(just shows source), I know people asked this 1 million times, But I looked over many of the questions and didn't find my solution as most of them using XML and I use java.. I am still not experienced enough to switch between the two.
conf.class :
public class conf extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/views/");
bean.setSuffix(".jsp");
return bean;
}
}
ServletInitializer.class:
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Demo4Application.class,conf.class);
}
}
welCont.class (Controller) :
#Controller
#RequestMapping("/spring/")
public class welCont {
#RequestMapping(method = RequestMethod.GET)
public String wel(ModelMap model)
{
model.addAttribute("test","testme");
return "welcome";
}
}
welcome.jsp :
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>${test}</h2>
</body>
</html>

I think wrong thing is
#RequestMapping("/spring/")
normally "/spring/" request should go to DispatcherServlet. Not sure in spring boot.
try with this.
#Controller
public class WelCont {
#RequestMapping(value="/foldername_if_avaiable/welcome/", method=RequestMethod.GET )
public ModelAndView wel(
#RequestParam(value="id", required=false) String id,
ModelMap model,
HttpSession session,
HttpServletRequest req) throws Exception {
model.addAttribute("test","testme");
return new ModelAndView("/foldername_if_avaiable/welcome", model);
}
}
reference

Related

Controller are not working in Spring

I unable to understand why my controller are not redirecting to my html. Anyone can help me please?
WebConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.udemy.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("");
return resolver;
}
}
HelloWorldController.java
#Controller
#RequestMapping("/example")
public class HelloWorldController {
public static final String EXAMPLE_VIEW = "example.html";
#GetMapping("/")
public String fileUploadForm(Model model) {
return "fileDownloadView";
}
#GetMapping("/helloworld")
public String helloWorld(){
return "helloworld";
}
// #RequestMapping(value="/exampleString", method=RequestMethod.GET)
#GetMapping("/exampleString")
public String exampleString(Model model){
model.addAttribute("name","John");
return EXAMPLE_VIEW;
}
// #RequestMapping(value="/exampleMAV", method=RequestMethod.GET)
#GetMapping("/exampleMAV")
public ModelAndView exampleMAV() {
ModelAndView mav= new ModelAndView(EXAMPLE_VIEW);
mav.addObject("name", "Mike");
return mav;
}
AppInitializer
public class MyWebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
My project structure is well done. So my html and jsps, are inside of the root WEB-INF/views. Also, the anotation #ComponentScan, are detecting the controller. So, its not a problem of root. Anyone can tell me, why im am not redirecting to the .html , please..
Error says:
ADVERTENCIA: No mapping found for HTTP request with URI [/spring-mvc-download-example/WEB-INF/views/example.html] in DispatcherServlet with name 'dispatcher'
In your controller class, above the
#RequestMapping("/example")
Insert:
#Controller
Gonna be:
#Controller
#RequestMapping("/example")
you have to annotate class HelloWorldController with #Controller or #RestController, only then it will be picked by #Componentscan annotation.

Configure spring boot to redirect 404 to a single page app [duplicate]

This question already has answers here:
Spring Boot with redirecting with single page angular2
(12 answers)
Closed 2 years ago.
I want to configure my Spring Boot app to redirect any 404 not found request to my single page app.
For example if I am calling localhost:8080/asdasd/asdasdasd/asdasd which is does not exist, it should redirect to localhost:8080/notFound.
The problem is that I have a single page react app and it runs in the root path localhost:8080/. So spring should redirect to localhost:8080/notFound and then forward to / (to keep route).
This is the full Spring Boot 2.0 example:
#Configuration
public class WebApplicationConfig implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/notFound").setViewName("forward:/index.html");
}
#Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/notFound"));
};
}
}
This should do the trick: Add an error page for 404 that routes to /notFound, and forward that to your SPA (assuming the entry is on /index.html):
#Configuration
public class WebApplicationConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/notFound").setViewName("forward:/index.html");
}
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/notFound"));
};
}
}
In case anyone stumbles here looking for how to handle Angular/React/other routes and paths in a Spring Boot app - but not always return index.html for any 404 - it can be done in a standard Spring controller RequestMapping. This can be done without adding view controllers and/or customizing the container error page.
The RequestMapping supports wild cards, so you can make it match against a set of well known paths (ie. angular routes etc.) in your application and only then return forward index.html:
#Controller
public class Html5PathsController {
#RequestMapping( method = {RequestMethod.OPTIONS, RequestMethod.GET}, path = {"/path1/**", "/path2/**", "/"} )
public String forwardAngularPaths() {
return "forward:/index.html";
}
}
Another option (borrowed from an old Spring article here: https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii) is to use a naming convention:
#Controller
public class Html5PathsController {
#RequestMapping(value = "/{[path:[^\\.]*}")
public String redirect() {
return "forward:/index.html";
}
}
The above configuration will match all paths that do not contain a period and are not already mapped to another controller.
//add this controller : perfect solution(from jhipster)
#Controller
public class ClientForwardController {
#GetMapping(value = "/**/{path:[^\\.]*}")
public String forward() {
return "forward:/";
}
}
Here the security configuration (SecurityConfig.java)
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
private UserSecurityService userSecurityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = {
"/css/**",
"/js/**",
"/data/**",
"/sound/**",
"/img/**",
"/",
"/login",
"/logout,
"/error",
"/index2",
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().
/* antMatchers("/**").*/
antMatchers(PUBLIC_MATCHERS).
permitAll().anyRequest().authenticated();
//.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");
http
.csrf().disable().cors().disable()
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/index2")
.loginPage("/login").permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
.and()
.rememberMe()
.and()
.sessionManagement().maximumSessions(3600)
.and().
invalidSessionUrl("/login");
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}
}
If not found any resource redirect to error page
#Controller
public class IndexController implements ErrorController{
private static final String PATH = "/error";
#RequestMapping(value = PATH)
public String error() {
return PATH;
}
#Override
public String getErrorPath() {
return PATH;
}
}
Error page like
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1000/xhtml"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<meta http-equiv="refresh" content="5;url=/login" />
<body>
<h1>Page not found please login the system!</h1>
</body>
</html>
Simply implementing the org.springframework.boot.web.servlet.error.ErrorController did the trick for me. I use SpringBoot 2.0 with React. (If you are interested in how to do that here is a boilerplate project made by me: https://github.com/archangel1991/react-with-spring)
#Controller
public class CustomErrorController implements ErrorController {
#Override
public String getErrorPath() {
return "/error";
}
}
I am not sure why is this working though.

The requested resource is not available when wanna map to .html file

I'm using Spring mvc, and wanna make web app which send some json data to client and client should visualized them using js.
I have some questions:
1-My project have some *.html beside *.jsp file how can I handle both without web.xml. the code that i had written work fine with *.jsp but give "The requested resource is not available." error for mapping html files.
2-As i said My service have to send a list of object in json form to client, when i want to parse the json string on server in *.jsp file with the code like
MyClass data = new Gson().fromJson(MyList.get(0).toString(), listType)
,I face with to many problems, so i decide to do this job in client Side in *.html file, i want to know how should i handle this parsing job when i don't want that client know about the structure my class? OR plz tell if have to share my class with client, how should i send stucture of it to html file?
3-How should i access to data that i created in restapi.jsp on the UserSideApp.html file?
these are some my files:
AppInitializer.java
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
} }
AppConfig.java
public class AppConfig {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix("");
return viewResolver;
} }
the part of my AppContoller.java
#Controller
#RequestMapping("/")
public class AppController {
#Autowired
HackDataService service;
#RequestMapping(value = "/restapi", method = RequestMethod.GET)
public String jsonAPI(ModelMap model) {
List<HackData> newList = service.findAllNewData();
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json="";
try {
json = ow.writeValueAsString(newList);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
model.addAttribute("List", json);
String newjson = new Gson().toJson(newList);
model.addAttribute("newList", newjson);
return "newTest.jsp";
}
#RequestMapping(value = "/app", method = RequestMethod.GET)
public String htmlapp() {
return "UserSideApp.html";
} }
and my both .html and .jsp files are in "/WEB-INF/views/"
After spending almost a day on first problem, i find the answer of it,
first of all instead of implementing WebApplicationInitializer, I extend AbstractAnnotationConfigDispatcherServletInitializer and for java Configing i extends WebMvcConfigurerAdapter.
Then i create a pages folder in WEB-INF and my codes changes to these:
AppInitializer became like other internet's samples.
AppConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.attackmap" })
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/WEB-INF/pages/");
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix("");
return viewResolver;
}
}
AppController.java
#Controller
#RequestMapping("/")
public class AppController {
#RequestMapping(value = { "/", "/info" }, method = RequestMethod.GET)
public String welcome(ModelMap model) {
model.addAttribute("message", "home page with info about site");
return "homepage.jsp";
}
#RequestMapping(value = "/finalapp", method = RequestMethod.GET)
public String test() {
return "redirect:/pages/final.htm";
} }
there was another way
Creating a "resources" directory in "src/main/webapp"
add bellow cod in AppConfig.java
registry.addResourceHandler("/WEB-INF/views/resources/*.html").addResourceLocations("/resources/");
and for viewResolving use the code like bellow:
#RequestMapping(value = "/newapp", method = RequestMethod.GET)
public String test2() {
return "/resources/UserSideAppNew.html";
}
but still my two other questions are unsolved, the main problem was first one but if you know sth, about these two plz tell me about them

Spring mvc 4 can't render jsp

I'm trying to learn Spring MVC 4 without using the web.xml but instead use the following:
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.html");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.bookstr.WebConfig");
return context;
}
}
and
#Configuration
#EnableWebMvc
#ComponentScan({ "com.bookstr.*" })
public class WebConfig {
}
For some reason the home.jsp file I have created and placed in the src->main->webapp folder will not be rendered when I use the following controller:
#Controller
public class HomeController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String getHome(Model model){
model.addAttribute("home", "Hello world");
return "home";
}
}
And the JSP file is the following:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>
${home}
</body>
</html>
Update!
Folder structure as requested.
I can see that the HomeController is not getting called.
Register a ViewResolver in your WebConfig:
#Configuration
#EnableWebMvc
#ComponentScan("com.bookstr")
public class WebConfig {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResover = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
This way, when you return the home from your controller, it will try to render the /WEB-INF/views/home.jsp view. For configuring DispatcherServlet programtically, it's easier to use AbstractAnnotationConfigDispatcherServletInitializer. For example, you simply can:
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/*.html" };
}
}

Spring MVC returns jsp as text/plain content type

I have a problem with Spring MVC and jsp webpage.
When I request a webpage, it returns as text/plain by default. I tried setting the content type as text/html manually at the HttpServletResponse controller, and the web browser reconigzes it, showing it correctly BUT encoding the jsp tags at the body. Example:
JSP:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>Error 405 ******* </title>
</head>
<body> asdasdsasad </body>
</html>
Browser receives:
<html>
<body><%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Title</title>
</body>
</html>
I'm using Spring Boot and java web based annotation for configuration. Also, I'm using #EnableAutoConfiguration, and I found that the problem is solved by mapping the sevlet from "/*" to "/".
Because of the java annotation, I had to override the dispatchedServlet (https://github.com/spring-projects/spring-boot/issues/91#issuecomment-27626036) and the configuration class is:
#Configuration
public class DispatcherConfiguration {
#Bean
public ServletRegistrationBean dispatcherRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet());
registration.addUrlMappings("/");
registration.setLoadOnStartup(1);
System.out.println("~~~~~~~ Servlet regristated " + registration.getServletName());
return registration;
}
#Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
Notice that I'm using the #Bean annotation missfollowing the previous comment link, because if not, Spring boot throws an exception. But even if not using the bean annotation, and using an xml the main problem is still here).
This is the Spring MVC configuration file:
#Configuration
#EnableWebMvc
#ComponentScan("es.sfacut")
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
// Maps resources path to webapp/resources
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/images/**").addResourceLocations("/resources/images/");
registry.addResourceHandler("/imgs/**")
.addResourceLocations(Constant.RESOURCE_IMAGES_PATH);
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
// resolver.setContentType("text/html");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
// Size in bytes
resolver.setMaxUploadSize(1752300);
return resolver;
}
}
Main class:
#EnableAutoConfiguration
#ComponentScan("es.sfacut")
#EnableJpaRepositories
public class TelocomproMain {
public static void main(String[] args) {
SpringApplication.run(TelocomproMain.class, args);
}
}
Controller:
#RestController
#RequestMapping(value = "/api/")
public class CategoryController {
#RequestMapping(value="test4", method = RequestMethod.GET, produces = "text/plain;charset=UTF-8")
public ModelAndView pageTest4(HttpServletResponse response) {
ModelAndView model = new ModelAndView("elovendo/index");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
return model;
}
}
Application.properties:
#View resolver
spring.view.prefix= /WEB-INF/views/
spring.view.suffix= .jsp
Not sure if I'm missing something, I'll post everything you need.
Thank you in advance.
Your controller should be a #Controller not a #RestController, otherwise the response will be returned as a string as you observe.
As mentioned already in the comments your custom configuration is not needed at all, you could have a look at the sample provided by the Spring boot team https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp.
Had the same issue.
It happens when you have your jsp in directory which is handled by ResourceHandler:
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
This is only for static recourses - img, css, js.
You should move your jsp outside

Resources