#RequestMapping not working in Spring Boot - spring

Controller class.
#RestController
#RequestMapping("/check")
public class Controller {
public String index(){
return "sdfksdjfkjkUshshdfisdfsdkasjdfjkasjdfkjakl:";
}
Application class
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
Added all the necessary dependency when running the application shows the
http://localhost:8081/demo/
Hello World
of index.xml
When I change to http://localhost:8081/check/ it gives
HTTP Status 404 – Not Found
Type Status Report
Message /check
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
How can I understand the flow of Spring Boot application?

You need to put the Http method on your method, here I am assuming you are doing a GET request
#RestController
#RequestMapping("/check")
public class Controller {
#GetMapping // you forgot to put http method here
public String index(){
return "sdfksdjfkjkUshshdfisdfsdkasjdfjkasjdfkjakl:";
}
Note: GetMapping is only available if you are using Spring 4.3 or above else use #RequestMapping(value = "/url", method = RequestMethod.GET)

Your controller should be like this:
#RestController
public class Controller {
#RequestMapping(value="/check")
public String index(){
return "sdfksdjfkjkUshshdfisdfsdkasjdfjkasjdfkjakl:";
}
}

It seems
#RequestMapping(value="/check") is not working.
switch to
#RequestMapping(path="/check")
though as per documentation it should work.

Related

Define front end controller for specific application in project

I created a front end controller within a project containing multiple (REST) applications. The issue is now that, the controller gets applied for all applications I try to access through the browser. I would like to ask whether the is a configuration or annotation to define for which application the controller should get applied.
This is the code of the controller:
#Controller
public class FrontendController {
#RequestMapping(value = "/")
public String index() {
return "index";
}
}
In the same package the application which serves the front end sources is implemented:
#SpringBootApplication
public class WebServer {
public static void main(String[] args) {
// Tell server to look for web-server.properties or web-server.yml
System.setProperty("spring.config.name", "web-server");
SpringApplication.run(com.studienarbeit.chaoscenter.services.departments.DepartmentsServer.class, args);
}
}
The other applications are in different packages and yet they still serve the front end sources. There are no other controllers in the project and the other applications use Spring Data REST repositories.
Note: Each application runs on its own port.
Note 2: I tried the approach using a profile for the controller:
#Profile("web-server")
Since I work with IntelliJ, I set the active profile to web-server and add the following flag in the VM Options for the specific application:
-Dspring.profiles.active=web-server
Somehow still my other applications access the front end controller. Maybe I did miss something?
Note 3: The other application implementations look basically exactly like the WebServer application and they use Spring Data REST repositories which look like this:
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
Use specific RequestMapping values for each of your controller classes like :
#Controller
#RequestMapping("/controller1")
public class FrontendController {
#RequestMapping(value = "/")
public String index() {
return "index";
}
}
So you would consume this endpoint with the url http://localhost:8080/controller1
Also, if you're not going to use Mvc Views and this will be only a Rest Controller, use #RestController insted #Controller.
#RestController
#RequestMapping("/controller1")
public class FrontendController
It's a combination of #Controller and #ResponseBody annotations. Detailed information could be found at here.

Spring Boot swagger file without UI

I have a simple service built in Spring Boot that has a simple API. I've added the springfox libraries to use swagger and the swagger UI, but I do not want my application to serve the UI also. I just want to get the definition from from /api/v1/api-docs
How do I switch off the UI part? Not adding swagger-ui library as a dependency doesn't remove the UI for some reason.
You can block the UI and return HTTP code 404. Something similar to below
#Controller //note - this is a spring-boot controller, not #RestController
public class HomeController {
#RequestMapping ("/swagger/api/v1/api-docs")
public String home(HttpServletRequest request) {
throw new ResourceNotFoundException(); //Custom Solution
or
throw new NoSuchRequestHandlingMethodException(request);
}
}
#ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
...
}
If you are using Spring Boot
#SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
#Bean
RouterFunction<ServerResponse> routerFunction() {
return route(GET("/swagger"), req ->
ServerResponse.temporaryRedirect("<some 404 page>").build());
}
}

Springboot #Controller cannot be invoked, but #RestController works

My controller has been annotated with #Controller and it cannot be invoked
- The browser shows
There was an unexpected error (type=Not Found, status=404).
But, if it is annotated with #RestController, then it works. My SpringBoot version:1.5.3.RELEASE
My Controller : (in com.sbootsecurityjsp.controller)
#Controller
public class LoginController {
#RequestMapping(value = "/login", method= RequestMethod.GET )
public String login() {
return "Login Controller";
}
}
Main Class: (in com.sbootsecurityjsp)
#SpringBootApplication(scanBasePackages = {"com.sbootsecurityjsp"})
public class SbootSecurityJspApplication {
public static void main(String[] args) {
SpringApplication.run(SbootSecurityJspApplication.class, args);
}
}
I am curious why the #Controller cannot work if the #RestController annotation works. If component scan is not working, #RestController also should not work. I have added scanbasePackages too. Even without scanbasePackages, it does not work.
By the way, when the app starts, the logs also show a line as following:
INFO 532 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login],methods=[GET]}" onto public java.lang.String com.sbootsecurityjsp.controller.LoginController.login()
Why #Controller is used is to differentiate requests to pages and rest calls. Please correct me if I am wrong. My idea is to use #RestController s for REST requests, on the other hand #Controller for pages related requests- redirecting to JSP or any logics related to views. Is it a bad practice ?
Why does it return a 404 when I use #Controller annotation?
When using #Controller, Spring expects the String you return in #RequestMapping methods to correspond to the page you want to redirect the user to.
#RequestMapping(value = "/login", method= RequestMethod.GET )
public String login() {
return "Login Controller";
}
Here, Spring will try to redirect the user to Login Controller.jsp, which cannot be found and thus returns a 404.
Why does it not return 404 when I use #RestController
When using #RestController, the String you return is not mapped to any page. Instead, Spring just transforms it to e.g. a JSON response. This is why this doesn't give you a 404.
Proposed solution
If you have a jsp page called login.jsp, simply return "login":
#RequestMapping(value = "/login", method= RequestMethod.GET )
public String login() {
return "login";
}

Spring RequestMapping with root path (/{custom})

Let's say my website name is: foo.com
When a user types foo.com, I want to show index.html.
When a user types foo.com/something, I want the server catches the request at the controller.
Here is what I did in the HomeController:
#Controller
public class HomeController {
#RequestMapping(value={"/"}, method=RequestMethod.GET)
public String getHome() {
return "index.html";
}
}
And, the CustomController should catch the request
#Controller
public class CustomController {
#RequestMapping(value={"/{custom}"}, method=RequestMethod.GET)
public String getCustom(#PathVariable String custom) {
// Do something here..
}
}
However, it throws an error: Circular view path [index.html]: would dispatch back to the current handler URL [/index.html] again. It's because the CustomController catches the GET request: foo.com/index.html after the HomeController returns the string: index.html.
I did some research like this:
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets"); // My asset
registry.addResourceHandler("index.html").addResourceLocations("file:/index.html");
} // It's not working
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/" + FileNames.INDEX);
} // This also not working
}
And changing the annotation from #Controller to #RestController in the CustomController is not an option.
Also, I don't have JSP files in the project - they are plain *.html files.
I am using Spring 1.3.3 release, so please help me out.
This solution works with ui-router (AngularJS library). Also, you have to change $resourceProvider setting:
// In your app module config
$resourceProvider.defaults.stripTrailingSlashes = false;
Then, in the Spring server codes, you can do this:
#RequestMapping(value = "/{custom:[^\\.]*}")
public String redirect(#PathVariable String custom) {
// Do something here...
return "forward:/";
}
Found the solution at this link: https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii

Spring Boot url mappings order for controllers and static pages

I have a Spring Boot web application which is meant to serve both static and controller based (ModelAndView) pages. Problem is that a controller can serve something like /{string} and a static page must be served with /test.
The problem is that the controller mapping takes precedence, and I need to avoid that. If the user hits /test, he must be forwarded to the test.html static page.
I tried to use the order property of ViewControllerRegistry in this way, with no success:
#Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("forward:/test.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE); // but I tried with 0 and -1 as well: annotated controllers should have order equals to 0
}
}
This is my SpringBootApplication class:
#SpringBootApplication
public class VipApplication {
public static void main(String[] args) {
SpringApplication.run(VipApplication.class, args);
}
}
And this is the controller code:
#Controller
public class VipController {
#RequestMapping(value = "/{string}")
public ModelAndView vip(#PathVariable("string") String string) {
ModelAndView mv = new ModelAndView("mypage");
return mv;
}
}
How can I reorder the mappings to make sure static pages are considered before annotated controllers?
(I'm not sure, but) I suggest to override WebMvcConfigurerAdapter.addResourceHandlers() method and configure order of resource handler by invoking ResourceHandlerRegistry.setOrder()

Resources