Two end points work without configuration - showing same view - spring

I am using Spring Boot (2.5.6)'s Controller like this:
#Controller
public class WebController {
#GetMapping("/index")
public String indexPage () {
return "index";
}
}
And when I hit these two URLs:
http://localhost:8080/index
http://localhost:8080
Same Thymeleaf view index.html is served. To my understanding on hitting http://localhost:8080 I should get - Whitelabel Error Page.
In the past I have used something like this #RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET) extensively. What I am missing/overlooking here?

Spring Boot, through auto-configuration, will add a WelcomePageHandlerMapping. The WelcomePageHandlerMapping will mimic the behavior of the welcome-page support in Servlet containers like Tomcat.
By default it will try to locate an index.html in either the static or template directory and, if needed, use the available templating framework to render this page.

Related

Spring Boot - Is it possible to disable an end-point

Assuming I have a controller like:
public class MyController {
public String endpoint1() {...}
public String endpoint2() {...}
}
I want to disable endpoint1 for whatever reason in Spring. Simply, just disable it so that it cannot be accessed. So, I am not looking for how and what response to return in that case or how to secure that endpoint. Just looking to simply disable the endpoint, something like #Disabled annotation on it or so.
SOLUTION UPDATE:
Thanks all who contributed. I decided to go with #AdolinK suggestion . However, that solution will only disable access to the controller resulting into 404 Not Found. However, if you use OpenApi, your controller and all of its models such as request/response body will still show in swagger.
So, in addition to Adolin's suggestion and also added #Hidden OpenApi annotation to my controllers like:
In application.properties, set:
cars.controller.enabled=false
Then in your controller, use it. To hide controller from the OpenApi/Swagger as well, you can use #Hiden tag:
#Hidden
#ConditionalOnExpression("${cars.controller.enabled}")
#RestController
#RequestMapping("/cars")
public class Carontroller {
...
}
After this, every end point handled by this controller will return 404 Not Found and OpenApi/Swagger will not show the controllers nor any of its related schema objects such as CarRequestModel, CarResponseModel etc.
You can use #ConditionalOnExpression annotation.
public class MyController {
#ConditionalOnExpression("${my.controller.enabled:false}")
public String endpoint1() {...}
public String endpoint2() {...}
}
In application.properties, you indicates that controller is enabled by default
my.controller.enabled=true
ConditionalOnExpression sets false your property, and doesn't allow access to end-point
Why not remove the mapping annotation over that method?
Try this simple approach: You can define a property is.enable.enpoint1 to turn on/off your endpoint in a flexible way.
If you turn off the endpoint, then return a 404 or error page, which depends on your situation.
#Value("${is.enable.enpoint1}")
private String isEnableEnpoint1;
public String endpoint1() {
if (!"true".equals(isEnableEnpoint1)) {
return "404";
}
// code
}

Spring - store object in session without MVC

I have a clean javascript + html + css frontend project, which sends a POST request to a backend endpoint.
Backend is a SpringBoot application.
I need to store a shopping cart into server's session and not into browser's session. Previously the project was a Spring MVC + Thymeleaf app, but I am rewriting it to JS + Spring.
In previous app version is was handled by #ModelAttribute and #SessionAttribute annotations, but simple "copy-paste" of all classes and configs does not solve the issue.
Example Controller:
#Controller
#SessionAttributes("basket")
public class LabelDesignController implements IPageModel {
#ModelAttribute("basket")
public Basket populateBasketForm() {
logger.info("[Model Attribute] populating [Basket] form.");
return new Basket();
}
#PostMapping(value = "/myEndPoint", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Object myEndPoint(#ModelAttribute("basket") Basket b, Item newItem) {
// some logic here
}
}
Item is a POJO class.
EDIT:
forgot to mention, the frontend are static HTML pages with vanilla JavaScript (even no jQuery). they are running on Nginx server. The backend is running on mvn spring-boot:run command.

Tomcat+Spring boot redirect ignoring contextPath

I'am using Spring boot and Tomcat7 to build a vehicle management system.
The base path is localhost:8080/vehicle
My server setting:
server.contextPath=/vehicle
My IndexController:
#RequestMapping("/")
public class IndexController extends BaseController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model) {
return "redirect:/login";
}
}
But when I go straight to get this view, my path is ...../login instead of ..../vehicle/login And so it returns 404 Error.
Also when I tried to use return "redirect:/vehicle/login"; it still goes to ...../login.
So what is wrong with my code. Why the server can't recognize the contextPath.
In application.properties use : server.servlet.context-path=/contextPath.
Example:
server.servlet.context-path=/vehicle
Tomcat Server:
In the webapps folder, the context path(vehicle) must be the same as the folder name(vehicle).

How to call Spring Boot (using tomcat) url redirect no template engine like localhost:8080/sample/someparameter

I am using spring boot+restful WS+ angular2. Mow my url is like http://localhost:8080/accountSummary/someparameter
When I run this I am getting error below in the browser
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Jun 30 16:24:03 EDT 2016
There was an unexpected error (type=Internal Server Error, status=500).
Circular view path [index.html]: would dispatch back to the current handler URL [/accountSummary/index.html] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
I have used below configurations in spring boot conf file under app folder:
#Controller
#Configuration
public class WebController extends WebMvcConfigurerAdapter{
// first option I have tried
/*public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/accountSummary/**").setViewName("index.html");
}*/
// second option I have tried
/* #RequestMapping(value = "/{[accountSummary:[^\\.]*}")
public String redirect() {
return "forward:/index.html";
}*/
Third option I have tried
#RequestMapping(value={"/accountSummary/{*}"}, produces="text/html")
public String getIndex(Model model, HttpServletRequest request){
return "index.html";
}
}
Presently this is show stopper to me. I am using pure spring boot structure like I am moving all the web application content into static folder under target folder.
You have been on the right path but used the wrong prefix. If you want to send a redirect you should use redirect: as a prefix instead of forward:.
It got fixed using Angular2. I have kept {provide:LocationStrategy,useClass:HashLocationStrategy}. if you give localhost:8080/#/ -- it will redirect to pagename with parameter if you provide.
Thanks to all for helping me.
#RestController
Add this annotation in your controller
#RequestMapping(value = "/accountSummary/someparameter", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
Add this on your method level and change according to yours method.

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

Resources