1

I am trying to map the URL /function/hash in my project to a specific HTML page html/hashcode.html. This is a spring boot project without using thymeleaf.

This is my code:

// package ...;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class FunctionController {
    @RequestMapping("/function/hash")
    public String hashPage(Model m) {
        return "html/hashcode.html";
    }
}

The above code returns a 404 when I try to access localhost:8080/function/hash.

I also tried

@Controller
@RequestMapping("/function")
public class FunctionController {
    @RequestMapping("/hash")
    public String hashPage(Model m) {
        return "html/hashcode.html";
    }
}

which also yields a 404 when I go to localhost:8080/function/hash.

Directly using @RequestMapping("/hash") to map the page to /hash works, in case you wonder if the return value of the function is incorrect.

I also find that using multiple layer url like @RequestMapping("/api/test") is working in @RestController classes, but somehow it doesn't work in this @Controller class above.

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
Power_tile
  • 578
  • 1
  • 6
  • 18

5 Answers5

1

Return "/html/hashcode.html"(prefix /), and create <project-root>/src/main/resources/static/html/hashcode.html

@Controller
public class FunctionController {
    @RequestMapping("/function/hash")
    public String hashPage(final Model m) {
        return "/html/hashcode.html";
    }
}

When return "html/hashcode.html":

o.s.web.servlet.DispatcherServlet        : "FORWARD" dispatch for GET "/function/html/hashcode.html", parameters={}

On the other hand, when return "/html/hashcode.html":

o.s.web.servlet.DispatcherServlet        : "FORWARD" dispatch for GET "/html/hashcode.html", parameters={}
  • Yes it worked! Turns out adding a prefix ```/``` before the ```html/hashcode.html``` is the correct answer. For other ```@RequestMapping```s in my project, having no ```/``` before ```html/some-other-page.html``` works fine when the link mapped to the file has no multiple layers (e.g. ```/main```, or ```/test```), which is so weird. Why would a ```/``` here make the difference? – Power_tile May 30 '20 at 06:07
0

use path in request mapping.

Ex:

@RequestMapping(path="/hash")

  • I tried both ```@RequestMapping(path="/function/hash")``` and using double annotation ```@RequestMapping(path="/function")``` plus ```@RequestMapping(path="/hash")```, but all of them yield 404 – Power_tile May 30 '20 at 03:59
  • It should work. Is it possible for you to share the code in GitHub ? – Sivaraj Velayutham May 30 '20 at 04:08
0

@RestController is combination of @Controller + @ResponseBody. While using @Controller we have to add the @ResponseBody with our methods. You can find more details here

@Controller
public class MappingController {

    @RequestMapping("/endpoint1") //returns 404
    public String endPoint1() {
        return "Hello endpoint1";
    }

    @RequestMapping("/endpoint2") //works well because of @ResponseBody
    public @ResponseBody String endPoint2() {
        return "Hello endpoint2";
    }
}

Add @ResponseBody and these both should work fine

@Controller
public class FunctionController {
    @RequestMapping("/function/hash")
    public @ResponseBody String hashPage(Model m) {
        return "html/hashcode.html";
    }
}

@Controller
@RequestMapping("/function")
public class FunctionController {
    @RequestMapping("/hash")
    public @ResponseBody String hashPage(Model m) {
        return "html/hashcode.html";
    }
} 
Romil Patel
  • 12,879
  • 7
  • 47
  • 76
  • Here I am trying to map this link ```/function/hash``` to an existing page in my project, namely ```html/hashcode.html```. Adding ```@ResponseBody``` will make this act as a ```@RestController``` which returns only a string containing ```"html/hashcode.html"```, which is not what I wanted. – Power_tile May 30 '20 at 06:05
0

add @ResponseBody annotation, The @Controller is a common annotation which is used to mark a class as Spring MVC Controller while the @RestController is a special controller used in RESTFul web services and the equivalent of @Controller + @ResponseBody

if u add @ResponseBody it will work. use below code

// package ...;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class FunctionController {

    @RequestMapping("/function/hash")
    public @ResponseBody String hashPage(Model m) {
        return "html/hashcode.html";
    }
}
  • Here I am trying to map this link ```/function/hash``` to an existing page in my project, namely ```html/hashcode.html```. Adding ```@ResponseBody``` will make this act as a ```@RestController``` which returns only a string containing ```"html/hashcode.html"```, which is not what I wanted. – Power_tile May 30 '20 at 06:03
0

If the html files are static resources, consider the static content support in Spring Boot.

Configure a spring.resources.static-locations to specify the resource localtions.

spring.resources.static-locations=file:/opt/files/,classpath:/static-files

And set the mapping pattern if you do not want to map it the root path.

pring.mvc.static-path-pattern=/content/**

(Or spring.webflux.static-path-pattern for Spring webflux application)

Now you can view the resources via http://localhost:8080/content/some.html

Hantsy
  • 8,006
  • 7
  • 64
  • 109
  • Here I am trying to avoid accessing the file directly and use a mapped link instead because of clarification reasons, so I used a ```@RequestMapping``` instead – Power_tile May 30 '20 at 06:10