Define front end controller for specific application in project - spring

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.

Related

Configure path prefixes for different WebAPIs in one Spring Boot App

I have a Spring Boot App with several WebAPIs. How can I configure the path prefix of each WebAPI differently via application properties?
For example I have a UserRestController and a StarShipRestController. Both are part of different WebAPIs, but served by the same Spring Boot App. The RestControllers should only feature the last part of the URL to the resource. The path prefix should not be part of the RestController:
#RestController
#RequestMapping("users")
class UserRestController {
// methods...
}
and
#RestController
#RequestMapping("starships")
class StarShipRestController {
// methods...
}
The concrete path prefixes are in application.properties:
api.user.pathPrefix=/api/v1
api.starship.pathPrefix=/universe
The question is how to apply the path prefixes to the RestControllers?
If there was only one WebAPI in the Spring Boot App, I could use a WebMvcConfigurer. But that doesn't work because I have several WebAPIs.
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("api", HandlerTypePredicate.forAnnotation(RestController.class));
}
}
You can only have one context-path for a single Spring-Boot application (which can be configured using server.servlet.context-path). This means what you are asking is not possible.
The only way to achieve it is by changing the #RequestMapping annotations in your Controllers to include the full path that you want.
#RestController
#RequestMapping("/api/v1/users")
class UserRestController {
// methods...
}
#RestController
#RequestMapping("/universe/starships")
class StarShipRestController {
// methods...
}
To my knowledge, there is no other way.
Considering your request, I ask myself if you shouldn't have two different Spring-Boot applications instead of just one.

White Label error Page in Spring boot in spite of having main and controller in same package

I am attaching the project structure.When I run as Spring boot application it shows white label errror. Since controller is in base package there is no need of component scan too.Can some one say whats the mistake.
Controller:
#Controller
public class HelloWorldController
{
#RequestMapping("/greeting")
public String greeting()
{
return "Hello World";
}
}
Use #RestController instead of #Controller if want to test you response output. Spring will treat this as rest controller. else, add #ResponseBody to your controller

#RequestMapping not working in Spring Boot

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.

Spring serving static content while having wildcard controller route

My application is build using backbone on frontend and spring framework on backend. It is a single html application. Routes are handled by backbone, so I have a backend route with the next structure:
#RequestMapping(value="/**", method=RequestMethod.GET)
public String Pages()
{
return "index";
}
To point everything to my index.html. The thing is that the static content
files are pointed to this route too, and I don't want this. I've tried to
config WebMvcConfigurerAdapter by overriding addResourceHandler method for
static content, but it doesn't work.
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/resources/js");
}
}
How can I point every route to my index.html except /js/** and /assets/** ?
Thank you
The first thing is that your controller method that's mapped to /** will be taking priority over any resource requests. You can address this by increasing the precedence of ResourceHandlerRegistry. Add a call to registry.setOrder(Ordered.HIGHEST_PRECEDENCE) in the addResourceHandlers method of StaticResourceConfiguration:
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
registry.addResourceHandler("/js/**").addResourceLocations("/resources/js");
}
}
The second thing is that, by default, Spring Boot configures two resource handlers for you by default, one mapped to /** and one mapped to /webjars/**. Due to the change described above, this will now take priority over the method in your controller that's also mapped to /**. To overcome this, you should turn off default resource handling via a setting in application.properties:
spring.resources.addMappings=false

Suggest MVC frameworks that do not use controller base classes

Pseudo-code:
class SomeController {
def myAction() {
// controler is an property passed via ctor
controller.redirect(toWhereever)
}
}
// another variant
class AnotherController {
def myAction(controller) {
// controler is an method argument
controller.redirect(toWhereever)
}
}
Any suggestions?
Edit: Because the question is a bit dry you could try to spice up your answers with some experience with the framework and what do you think is better with that approach.
Spring MVC and Grails (built ontop of spring) favour dependency injection with no inheritance whatsoever. Each controller is a class that does not extend anything. Instead you can inject other components into it (using dependency-injection). For example:
#Controller
#RequestMapping("/user")
public class UserController {
#Inject
private UserService service;
#RequestMapping("/register")
public String register(User user) {..}
}
#Controller
#RequestMapping("/orders")
public class OrderController {
#Inject
private UserController userController
}
(Although it is not a common practice to inject controllers into other controllers, you can inject any object)
web2py - controllers are functions
web.py
puremvc - controllers are Commands
camping - odd, replaces internal controllers
limonade - procedural
Django has decided to use different terms for the MVC pattern. In django-speak "view" is what most people call controller. a django view is just a function taking a request instance and returning a response instance. Roughly it looks like this:
from django.http import HttpResponse, Http404
import datetime
def current_datetime(request):
if request.method != 'GET':
raise Http404
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
JSF & Spring MVC
An easy tutorial for JSF: www.coreservlets.com/JSF-Tutorial/jsf2/index.html#Annotations
A basic example from SpringSource: http://src.springframework.org/svn/spring-samples/mvc-basic/trunk
Q: Why JSF
A:
You can perform your action at SimpleController#doSomething
#ManagedBean
public class SimpleController {
public String doSomething() {
...
}
}
And SimpleController does not extend any controller, #ManagedBean helps to make it look like a controller.
Q: Why Spring MVC
A:
You can perform your action at "..../doSomething"
#Controller
public class SimpleController {
#RequestMapping("/doSomething")
public String doSomething() {
...
}
}
SimpleController does not extend any controller.
#Controller helps to make the class a controller
#RequestMapping bind its url to "/doSomething"
[sorry for bold url, i can only post maximum one url in an answer as a newbie :-S]
Struts 2 also lets you do this. All the actions are simple java beans.

Resources