I'm struggling with trying to return a static web page from a spring MVC controller.
I followed this tutorial: http://www.tutorialspoint.com/spring/spring_static_pages_example.htm and yet it still isn't working.
This is how I defined the configuration (used configuration class):
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan({ "com.my.web.api"})
#ImportResource("classpath:db-context.xml")
public class ApiServletConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("/resources/");
internalResourceViewResolver.setSuffix("*.html");
return internalResourceViewResolver;
}
}
The controller method:
#RequestMapping(value = "/{id}/view", method = RequestMethod.GET, produces = "text/html")
#ResponseBody
public String getPostByIdHtml( #PathVariable String id) throws IOException {
return "/resources/Post.html";
}
Under the webapp folder there's a folder named "resources" and under which there's a file "Post.html". What else should I do in order to get this page returned as HTML instead of getting the string "resources/Post.html"?
Thanks for the help.
Please remove the annotation #ResponseBody. Your browser should be redirected to the desired page once the annotation is removed.
This annotation indicates that the value returned by a method in your controller should be bound to the web response body. In your case, you do not need that: you need Spring to render page /resources/Post.html, so no need for this annotation.
Related
I just start learning SpringBoot.
I use spring boot build-in tomcat get my spring boot program run. But when I try to visit the page, it gives me a Whitelabel Error Page.
When I start this program, it shows as follow:
I think my program and tomcat start successfully.
This is my start code:
DemoApplication.java
#SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
This is my Controller code:
BookController.java
#Controller
public class BookController {
private IBookService bookService;
public BookController(IBookService bookService) {
this.bookService = bookService;
}
#RequestMapping(value = "/book_list", method = RequestMethod.GET)
public String getAllBook(Model model, HttpSession httpSession, HttpRequest httpRequest) throws Exception {
List<Book> list = bookService.getAllBook();
model.addAttribute("bookList", list);
return "book";
}
}
So if I visit 'localhost:8080/bookstore/book_list', it will find the controller and this controller should help me go to the /WEB-INF/jsp/book.jsp because my WebMvcConfig like following:
WebMvcConfig.java
#Configuration
public class WebMvcConfig {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
But why this is a white page?
This is my program structure:
DemoApplication is in a demo subpackage. The default is that it only scans subpackages of the class annotated with #SpringBootApplication, so it doesn't find any of your components.
Two ways to fix:
Move the class out of the demo package.
This is what Spring Boot demo applications usually do.
Specify the packages to scan:
#SpringBootApplication(scanBasePackages = "com.zx")
Alternatively, use #ComponentScan, same thing:
#SpringBootApplication
#ComponentScan("com.zx")
I know this question has a lot of answers but i cannot solve mine so that is why i decided to put up the question
I want to resolve both jsp and html files. Below is my spring resolver configuration
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("");
return resolver;
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/views/static");
}
and controller class is below:
#RequestMapping("/testApi2")
#Controller
public class TestController2
{
#RequestMapping("/showHomePage")
public ModelAndView showHome(){
return new ModelAndView("/static/about.html");
}
}
I have also attached screen shot of my directory structure, it is giving 404 on every request
I think that you should add to your web resolver config class one very special handling configurer:
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
This method enables static resources processing.
After some efforts , thanks to lot of documentation on Spring , i was able to resolve the issue
I found a solution(searched on net) with which we can use both JSP and HTML as views
Forget the question , below are the new settings
Static resources (.css,.js,.jpg) are placed in webapp/assets/
HTML files are in /WEB-INF/static/
Here is my configuration file :
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**") //
.addResourceLocations("/assets/").setCachePeriod(31556926);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
Please note i have used resolver.setSuffix("") both HTML and JSP
HTML code :
<link rel="stylesheet" href="/taxi/assets/css/theme-pink.css" />
Here taxi is the context root , means name of the project
Now if i run the below URL , it will fetch the image or CSS of js
localhost:8080/taxi/assets/css/icons.css
I use spring mvc with spring configuration (without xml). And it seems like IDEA doesn't go to controller code. Maybe somewhere path is incorrect so #RequestMapping doesn't work. But i can't understand where exactly.
Here is my Controller
#Controller
public class MainController {
#RequestMapping(value = "/" , method = RequestMethod.GET)
public String home() {
return "index";
}
#RequestMapping(value = "welcome", method = RequestMethod.GET)
public String welcome(Model m){
m.addAttribute("name","lol kkeke");
return "index2";
}
}
WebMvcConfig
#Configuration
#ComponentScan("com.chat")
#EnableWebMvc
public class WebMVCConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/scripts/**").addResourceLocations("/scripts/");
registry.addResourceHandler("/styles/**").addResourceLocations("/styles/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/");
registry.addResourceHandler("/pages/**").addResourceLocations("/views/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("/index.jsp");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
}
So.. I solved a problem. It was in Controller - path. My Idea automatically change path from com.chat.controller to c.c.controller. So i rebuild project structure to com.chat.controller.Controller.class; and com.chat.config.Configuration.class.
Also, i found the next article about similar trouble. May be it will help somebody! How do I map Spring MVC controller to a uri with and without trailing slash?
My Project structure is as follows
|src
|--main
|---webapp
|----static
|-----CSS
|-----HTML
|-----js
I am trying to return an HTML resource via my controller for links that are directly under root there is no issue but for other links, I am facing problems.
Here is my controller
#Controller
public class HtmlServer {
#RequestMapping({"/", "/index", "/index.html", "/index.jsp", "/home","/home.html","/home.jsp"})
public ModelAndView index() {
return new ModelAndView("html/index.html");
}
#RequestMapping(method = RequestMethod.GET, value = "/support/{id}/{accessToken}")
public ModelAndView start(#PathVariable Long id, #PathVariable String accessToken) {
return new ModelAndView("html/index.html");
}
}
Here is my WebMvcConfigurerAdapter extending class
#Component
#ConfigurationProperties
#Configuration
#EnableWebMvc
public class ApplicationConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver internalResourceViewResolver(){
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("static/");
return internalResourceViewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("static/js/")
.setCachePeriod(0);
registry.addResourceHandler("/css/**").addResourceLocations("static/css/")
.setCachePeriod(0);
registry.addResourceHandler("/support/**").addResourceLocations("/static/")
.setCachePeriod(0);
}
}
When I open / or /index.html the controller returns the given value and in return i am served the correct resource.
But when I try to use /support/1/xsdda I am mapped to /support/1/static/html/index.html Can someone explain the internals and logically point out my mistake.
Thanks!
Create folder WEB-INF inside webapp and put your HTML folder inside it
set prefix of resolver to /WEB-INF/HTML/
set suffix of resolver to .html
call it by returning "index"
The Servlet 2.4 specification says this about WEB-INF (page 70):
A special directory exists within the application hierarchy named
WEB-INF. This directory contains all things related to the
application that aren’t in the document root of the application. The
WEB-INF node is not part of the public document tree of the
application. No file contained in the WEB-INF directory may be served
directly to a client by the container. However, the contents of the
WEB-INF directory are visible to servlet code using the getResource
and getResourceAsStream method calls on the ServletContext, and may
be exposed using the RequestDispatcher calls.
The only relevant question I could I find here is this one.
Unfortunately unlike the above mentioned question I am not using file names as a path variable. What I am sending in a string which may or may not have '.'. As a result I do not want to use a strategy mentioned in the solution for the above question.
This is my WebConfigAdapter:
#Configuration
public class WebConfigAdapter extends WebMvcConfigurerAdapter {
#Autowired
HandlerExceptionResolver exceptionHandler;
/**
* Disable content negotiation for path extensions.
*
* #param configurer
*/
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
/**
* Set the exception handler.
*
* #param exceptionResolvers
*/
#Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
super.configureHandlerExceptionResolvers(exceptionResolvers);
exceptionResolvers.add(exceptionHandler);
}
/**
* Serve static resources.
*
* #param registry
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
I import WebConfigAdapater in my WebConfig (a java file) like so:
#Configuration
#EnableWebMvc
#Import(value = { WebConfigAdapter.class, WebConfigSupport.class })
public class WebConfig {
#Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public HandlerExceptionResolver exceptionHandler() {
return new ExceptionHandler();
}
}
And in my application context xml:
<bean class="com.quova.platform.portal.config.WebConfig"/>
I still cant figure out when I use Spring mock mvc in my unit tests, why the below controller receives the string input it strips off the characters after the last period in the string including the period.
#RequestMapping(value = "/{ip}", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public Info lookup(#PathVariable("ip") String ip) throws Exception {
Here's how I am calling the above endpoint in my unit test:
String ip = "4.3.2";
mockMvc.perform(get("/secure/resources/iplookup/{ip}", ip)).andExpect(status().isBadRequest());
So now what the controller sees is "4.3". Also this is my first question on stack overflow, so do let me know if i am missing some needed information or can explain better my question in a better way! Thanks for the help!
#RequestMapping(value = "/{ip:.*}", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public Info lookup(#PathVariable("ip") String ip) throws Exception {
This works