Spring, Why does the controller work 3 times? - spring

I finished the initial setup using a combination of Spring Framework + Maven.
No special work was done and only minimal installation was performed.
It consists of one most basic controller and one JSP (basic index) file.
So when I run the server, the System.out.println statement I wrote down as an example in the controller is executed a total of 3 times.
Why is that?
#Controller
public class mainController {
#RequestMapping(value="/")
public String main() {
System.out.println("why?");
return "index";
}
}

Related

Spring RestController catch all RequestMapping and continue to the correct endpoint

Say I have a #RestController like below:
#RestController
#RequestMapping("/1st")
public class MyController {
#GetMapping("/2nd/aaa")
public void getAaa() {
...
}
#GetMapping("/2nd/bbb")
public void getBbb() {
...
}
}
I want to add methods to catch all requests with the base path "/1st" and "/1st/2nd" in between and then continue to the correct endpoint. I tried adding:
#GetMapping("/**")
public void doThisFirst() {
...
}
But that didn't work, a request to "/1st/2nd/bbb" still only landed on the method getBbb() only. Please help, thank you.
I want to add methods to catch all requests with the base path "/1st"
and "/1st/2nd" in between and then continue to the correct endpoint. I
tried adding:
#GetMapping("/**") public void doThisFirst() {
... }
Probably you want to execute some extra code (code in doThisFirst) before you execute the respecting code that each endpoint have.
There are 2 solutions here.
A) You define an aspect with #Before that will be executed before the code that your final endpoint has. Here is some example code
B) You define an interceptor which will be executed only before those 2 endpoints. Check here some previous SO answer.
Either the interceptor or the aspect should contain the code that you have in doThisFirst() and you want to execute before you reach the actual endpoint.
In every case this starting code should not be inside a controller, so you can remove the #GetMapping("/**") from the controller.

Spring Boot - mapping

In the code below there are two methods annotated with #GetMapping annotation, one expects empty path, another one expects a path variable.
#Controller
#RequestMapping("/")
public class BasicController {
#GetMapping()
public String get(Model model) {
// doing something
}
#GetMapping("/{variable}")
public String getWithPathVar(#PathVariable("variable") String variable, Model model) {
// doing something different
}
}
Problem: When the app is running and I hit "www.myurl.com/" it enters both methods even though there is no path parameter. How can I fix this?
If so it sounds like a bug or some misconfiguration with filters. I can't reproduce this behaviour on the Spring 5.2.7. Here's an article that explains how Spring works under the hood.
If you can't upgrade the Spring version you can use only single endpoint as a workaround.
#GetMapping("/{variable}")
public String getWithPathVar(#PathVariable("variable") String variable, Model model) {
// doing something different
if(variable != null) {
// fulfill the normal workflow
} else {
// call ex get() workflow
}
}

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

Spring Controller - forking request, return value before long run function ends

I have controller and long run function in it, like:
#Controller
#RequestMapping("/deposit")
public class DepositController {
#RequestMapping
public ModelAndView getNewJob(long userId, Model model) {
//execute function that can runs a lot of time ...
longRunFunction();
return new ModelAndView("jobTasks");
}
public void longRunFunction(){
// process long run function
}
}
My question is :
How can I execute the longRunFunction()
and return ModelAndView("jobTasks") answer to the browser without waiting for the end of the function?
Thank you !
Hi, I found nice example here http://krams915.blogspot.co.il/2011/01/spring-3-task-scheduling-via.html
This can be done using Asynch support in Spring Framework, essentially delegate the long running task to another service, the method of which is annotated with #Async annotation, this task would then be executed by a threadpool and control will return back to your caller immediately.
Here is much more detailed reference: http://docs.spring.io/spring-framework/docs/3.2.3.RELEASE/spring-framework-reference/html/scheduling.html#scheduling-annotation-support-async
public class SampleBeanImpl implements SampleBean {
#Async
void longRunFunction() { … }
}
Add #Async to the method declaration of longRunningMethod. But to make this work without AspectJ weaving you need to put this method in an other bean.

spring mvc 3 caching example

I have requirement for spring mvc 3 caching. Requirement is : while starting the server, we need to call database for one dropdown and put those values in the cache. So that whenever we required those values, we need to retrieve from cache.
Please help me with an example.
Thanks in advance.
May be you can use init-method (Spring 2.5) or #PostConstruct annotation (in Spring 3.0).
This method will be called during server start up
The following is code snippet
#Component
public class CacheDBData {
private String values[];
//add setter & getter
//This will be called during server start up after properties are initialised
#PostConstruct
public void getDataFromDB() {
values = //Logic to get data from DB and store that in values property
}
}
Suppose for example you can use in class as follows
#controller
public class HomeController {
#Autowired
private CacheDBData cacheDBData ;
//getter and setters
private void methodxyz() {
String values[] = cacheDBData.getValues();
}
}
I've had success with Ehcahe for Spring. There's a couple of config files to setup but after that you simply annotate the methods you want to cache the output from and it just works.
This has the advantage that you can change the values coming back from the service/database and NOT have to restart your app, unlike the accepted answer.

Resources