Change default homepage for Roo generated app using SpringMVC - spring

By default when the web app starts it starts with the home page generated by roo with view name as "index"
Suppose i add new custom controller using following command,
web mvc controller ~.web.ViewHomeController --preferredMapping /homepage1
It generates the following code,
#RequestMapping("/homepage1/**")
#Controller
public class ViewHomeController {
#RequestMapping
public void get(ModelMap modelMap, HttpServletRequest request,
HttpServletResponse response) {
}
#RequestMapping(method = RequestMethod.POST, value = "{id}")
public void post(#PathVariable Long id, ModelMap modelMap,
HttpServletRequest request, HttpServletResponse response) {
}
#RequestMapping
public String index() {
return "home/homepage1";
}
}
I want the "home/homepage1" page to be the default page to be shown when the Roo Application starts.
Can i please get some guidance/details on changes i need to make to enable "home/homepage1" as default homepage for my application.
Thanks for help in advance. I am using latest version of Spring ROO, 1.1.4.
Thanks

In your webmvc-config.xml, replace the following section:
<!-- selects a static view for rendering without the need for an explicit controller -->
<mvc:view-controller path="/" view-name="index" />
with a view name you prefer.

Related

Spring sending user to a view when no view is being requested

I have written a book catalog in Spring.
It collects books (pdf, epub, mobi, ebook) from a directory, collects some metadata from them, stores them in a DB and then puts them in a List that is made available to my views:
#Slf4j
#Controller
public class BookCatalogController {
// == Fields ==
private final BookService bookService;
#Autowired
public BookCatalogController(BookService bookService){this.bookService = bookService; }
// == Model attributes ==
#ModelAttribute
public List<Book> bookData(){ return bookService.getBooksFromMemory(); }
public static final File bookDirectory= new File("D:\\edu_repo\\ebooks_test\\");
.
.
.
// Catalog Simple View
#GetMapping(Mappings.CATALOG_SIMPLE)
public String catalogSimple(Model model){
log.info("catalogSimple method called");
// This is adding the entire BookManager book list into the model.
model.addAttribute(AttributeNames.BOOK_DATA, bookData());
return ViewNames.CATALOG_SIMPLE;
}
// Catalog Detail View
#GetMapping(Mappings.CATALOG_DETAIL)
public String catalogDetail(Model model){
log.info("catalogDetail method called");
// This is adding the entire BookManager book list into the model.
model.addAttribute(AttributeNames.BOOK_DATA, bookData());
return ViewNames.CATALOG_DETAIL;
}
.
.
.
#GetMapping(Mappings.LOAD_BOOKS)
public void loadBooks(Model model) {
bookService.loadBooksFromDirectory(bookDirectory);
}
}
Obviously I'm not using #GetMapping(Mappings.LOAD_BOOKS) properly as you can see in the error below:
The error:
There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template [load-books], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [load-books], template might not exist or might not be accessible by any of the configured Template Resolvers
How does one invoke a method like I am doing but without Spring trying to redirect the user to another view?
I'm not expecting the page to update at all since I'm not returning a View!
When you click a link in your browser with a load-books anchor, your browser sends it to the server and waits for result, which causes your page to be reloaded. Once the request to a load-books endpoint reached to the server, Spring MVC handles this and starting to looking up an appropriate controller with its method. It founds public void loadBooks(Model model) in your case. When Spring MVC invokes the method, it expects to obtain a view name to resolve and return back to your browser.
Since you haven't provided a View or String as a return type, Spring MVC used the endpoint's path as a view name (I'm not seeing your Mappings.LOAD_BOOKS constant, but it supposed to be load-books).
If you're not going to return any view back to the browser, you can annotate the method like that:
#GetMapping(Mappings.LOAD_BOOKS)
#ResponseBody
public void loadBooks(Model model) {
which tells Spring to treat void as a response body.
But it's not preventing a page refreshing, you'll just see an empty page after clicking the link. In order to fix this you can redirect a user to another page by returning the following string (without ResponseBody annotation on the method)
return "redirect:/path-to-redirect";
When Spring MVC sees this prefix it redirects you to another controller, but user going to notice that too.
If you really don't want to see a blank page for a moment, you'll have to use some JavaScript to perform AJAX request to the server when button is clicked.
Actually, it seems that you want to preload some files in a service by a given path. If it's all you want to do, you can use Spring's runners like that:
#Component
class Preloader implements ApplicationRunner {
private final BookCatalogService bookService;
#Autowired
public Preloader(BookCatalogService service) {
this.bookService = service;
}
#Override
public void run(ApplicationArguments args) throws Exception {
bookService.loadBooksFromDirectory(BookCatalogController.bookDirectory);
}
}
Spring automatically calls all registered runners when application is ready, so your code will be executed without having a user to visit load-books endpoint.

flash attribute not working depending on the the redirect URL

I tested the below using Spring web MVC 4.3.5.
The following controller shows an example of a flash attribute working properly after a redirect:
#Controller
#RequestMapping("/redirection")
public class RedirectionController {
private static final Logger logger = Logger.getLogger(RedirectionController.class);
#RequestMapping(path="/pageA", method=RequestMethod.GET)
public String foo(RedirectAttributes redirectAttributes
, HttpServletRequest request
) {
redirectAttributes.addFlashAttribute("foo", "bar");
return String.format("redirect:%s", "/redirection/pageB.do");
}
#RequestMapping(path="/pageB", method=RequestMethod.GET)
public String boo(final HttpServletRequest request, final Model model) {
printModelAttributes(model);
return "page-b";
}
private static void printModelAttributes(final Model model) {
Map<String, Object> map = model.asMap();
logger.info(String.format("model attributes are: %s", map.keySet()));
}
}
When we visit the /pageA path with our browser we are automatically redirected to /pageB and the controller method for /pageB sees the flash attribute as expected:
14:35:18,740 INFO [webgui.RedirectionController] (http-/127.0.0.1:8082-3) model attributes are: [foo]
However, if I change the return statement the produces the redirect String from:
return String.format("redirect:%s", "/redirection/pageB.do");
… to:
return String.format("redirect:%s", "/.."+request.getContextPath()+"/redirection/pageB.do");
… we are still redirected to the same /pageB path but this time the flash attribute is missing:
14:34:51,892 INFO [webgui.RedirectionController] (http-/127.0.0.1:8082-3) model attributes are: []
I am assuming that this is due to Spring MVC trying to be clever and trying to guess if the redirection will take us to another application (different context path) in which case it does not bother placing the flash attributes in the session as they won't be available anyways in the other application.
Apparently the presence of the /.. in the redirect String causes Spring MVC to think that we are changing application.
My questions are:
is this feature documented?
is my explanation plausible or is this a bug?

spring-boot application displaying html code for view when executed in the browser

I am recently start to work with spring-boot in my spring projects, and right now I am facing this problem:
I have one spring-boot application with this main class:
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and this controller:
#Controller
public class AcessoController {
#RequestMapping(value = "/signin")
public String signin(Model model) {
return "acesso/signin";
}
#RequestMapping(value = "/admin")
public String admin(Model model) {
return "private/admin";
}
#RequestMapping(value = "/index")
public String index(Model model) {
return "public/index";
}
}
when I run the application and try access the url mapping /signin, for example, the browser display the html code for this view, instead of the actual content.
What I am doing wrong here?
Are you trying to render a view using a template engine, or just return a static HTML file?
If you are trying to render a template, then you most likely do not have the right dependency in place to pull in a template engine. (Per your code, I believe this is what you are trying to do.) Even if you don't intend to use the template engine for templates, you will want one to render the HTML for you. Depending on your spring-boot setup, try starting with spring-boot-starter-web, or pull in Thymeleaf (spring-boot-starter-thymeleaf) or Freemarker (spring-boot-starter-freemarker) specifically.
If you want to simply return static content and do not want do custom configuration, you'll need to place the files in a certain location and do not need specific controller request mappings.
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-static-content

How to use send.redirect() while working with Spring MVC

I was trying to redirect to a dynamic page from Interceptors and Handler Mapping program. I have already defined a controller which handles and redirects (/hello.htm) through model (I have only this controller in my program). Until this point it is working fine. Apart from this, I registered a handler which will redirect to a page once it satisfies some condition.
public class WorkingHoursInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("In Working Hours Interceptor-pre");
Calendar c=Calendar.getInstance();
if(c.get(Calendar.HOUR_OF_DAY)<10||c.get(Calendar.HOUR_OF_DAY)>20){
response.sendRedirect("/WEB-INF/jsp/failure.jsp");
return false;
}
return true;
..............
..............
}
But once it comes to response.sendRedirect, it is showing resource not found even though the mentioned page is present. I tried to redirect to "WEB-INF/jsp/hello.jsp" as well but keeps showing the same error. If the condition in the interceptor is not satisfied, the program works fine.
Below is shown the only controller present in the program.
#Controller
public class MyController {
#RequestMapping("/hello.htm")
public ModelAndView sayGreeting(){
String msg="Hi, Welcome to Spring MVC 3.2";
return new ModelAndView("WEB-INF/jsp/hello.jsp","message",msg);
}
}
(The controller for handling hello.html works fine if I change the interceptor condition)
Instead of redirecting, if I just print a message in the console, the program works fine. But once it comes to redirect it shows the error. Do I need to specify a separate controller to handle this request? Will this redirection request go to the dispatcher-servlet?
You need to add redirect: prefix in the view name, the code for redirect will look like:
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect() {
return "redirect:finalPage";
}
OR
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView redirect() {
return new ModelAndView("redirect:finalPage");
}
You may get a detail description from here:
enter link description here

Set the base URL in the page when using Spring MVC 3

I am learning the Spring MVC 3 now.
I meet some problems when set the URLs in my page, since the URL in the page are relatived to the current page, so I want to set the base URL in each page.
When I use Structs 2, I create a BaseAction like this:
public class BaseAction{
public BaseAction(){
string baseURL=getServletContext.getHost()+"...."+.....;
}
public getBaseURL(){xxxxx}
}
Then in the page:
<base href='<s:prototype value="baseURL"/>' />
Now, in Spring MVC 3, since the a new instance of related controller is not created for each request, so I do not know how to make it?
Finally, I think I can use the interceptor, so I create a interceptor:
public class BaseURLInterceptor extends HandlerInterceptorAdapter{
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
return true;
}
//after the handler is executed
public void postHandle(
HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView)
throws Exception {
modelAndView.getModel().setObject("baseURL",requset.getHost()+"......");
}
}
In the page:
I can use :
<base href="${baseURL}" />
It works, however when a view is redirected, it will add this value to the URL.
For example:
#Controller
#RequsetMapping("/user")
public class UserController{
#RequsetMapping("edit/{userid}")
public String edit(#PathVariable String uid)
//edit logic
return "redirect:list"
}
#RequsetMapping("list")
public String list(){
//get users list
return "user_list"
}
}
When I make the submit button in the user edit page, I will redirect to :
http://localhost:8080/app/user/list?baseURL=http://localhost:8080
Where the parameter in the url ?baseURL=http://localhost:8080 is not what I want.
How to fix it?
Or what is the better way to solve the URL path using Spring MVC 3?
May I do not correct understand the problem, but if you want to have the base url in the jsp for some links than your approach is the wrong one.
normaly you would do something like this:
test
And for redirects in the controller you can specify how the url has to be interpreted if you use RedirectView instead of returning the String "redirect:xxx": the redirect view constructor RedirectView(String url, boolean contextRelative) can be used to specify context relative to the current ServletContext or relative to the web server.
If I understand the problem correctly this is what you're looking for <base href="<c:url value="${webappRoot}" />

Resources