I have a controller and my requirement is to call a method of controller from a new class.
Suppose this is my method
#SuppressWarnings("unchecked")
#Timed
#RequestMapping(value = "/loadProductsRailWidget/", method = RequestMethod.GET)
public ModelAndView getProductsRailWidget(){
/////some code here
return modelAndView;
}
and I want to call this method from
public class TestRepeat {
#Timed
public void repeat() {
System.out.println("Called... AT :: " + Calendar.getInstance().getTime());
}
}
let me know how can I do this, thanks in advance.
You can create an instance of your controller from your class and invoke the method. But this will not give you any of the wired components, as this is a regular way of calling classes and its no advisable.
TestController tC = new TestController();
tC.getProductsRailWidget();
The other way is get the controller from ctx.getBean("");
Related
This is my controller class
#Controller
public class myClass extends BaseController {
#RequestMapping(value = "/myList", method = RequestMethod.POST, consumes = "application/json")
public #ResponseBody MyBaseVO getMyList(#RequestBody MyBaseVO requestObj) throws Exception {
requestObj.setEntity(getConfig(LanguageConstant.MY_MODULE_ID));
MyBaseVO response = (MyBaseVO) this.execute(requestObj,LanguageConstant.MY_MODULE_ID);
return response;
}
}
I wanted to write a mock test case but stuck at this point, also i'm not sure i am doing correct or not. Can anyone help me in this.
public class myClassTest{
myClass spy = Mockito.spy(new myClass ());
Mockito.when(spy.getMyList(itemRequest)).thenReturn(itemReq);
}
I am not sure how to use url myList in testcase and request and response object. I have created a json file of my request and response. Since it is using parent class therefore I am using spy for my testcase.
Since you are using Spring, you should have a look at Spring's platform Mock Test implementation for Spring MVC.
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#spring-mvc-test-framework
I have 2 class with 2 same URL mappings:
#RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(#PathVariable(TOPIC_ID) Long topicId) {
...
}
//
#RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodB(#PathVariable(TOPIC_ID) Long topicId) {
...
}
MethodB is in a class that is loaded dynamically. I want use methodA only if methodB is not available. If methodB is available the Spring uses only it.
How can I do that.
It sounds really confusing to sometimes have the URL mapping come from one package and sometimes from another. Why don't you do as Ken Bekov suggested in a comment and have just one class where there's the URL mapping and have that class dynamically decide which implementation to use? So something like this:
#RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(#PathVariable(TOPIC_ID) Long topicId) {
Class classWithMapping;
try {
classWithMapping = Class.forName("class.that.MayNotExist");
} catch(ClassNotFoundException cnfe) {
classWithMapping = MyDefaultClass.class;
}
// ....
}
...and then instantiate classWithMapping using reflection or Spring's application context.
The spring way would be to have only one controller mapped to an URL, and to inject the dynamic class that actually does the job in it:
class A {
#Autowired(required = false)
class B b; // inject by Spring or by ... or not at all
...
#RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(#PathVariable(TOPIC_ID) Long topicId) {
if (b != NULL) { // class B has been found and injected
return b.methodB(topicId)
}
// fallback ...
...
}
}
class B {
// NO #RequestMapping here !
public ModelAndView methodB(#PathVariable(TOPIC_ID) Long topicId) {
...
}
}
In spring, a controller object is a singleton bean in spring context, and the context is initialized during starting. So, if a class is dynamically loaded, the request mapping will not be applied. So you can not do what you said.
The solution above of ZeroOne is the only way I think.
I have a controller which handles a specific URL
#RequestMapping(value= {"/myurl"})
public ModelAndView handleMyURL()
Instead I want to have 2 separate controllers that let me handle this same /myurl based on the parameters passed to it.
If URL is
/myurl?a=1
goto controller A, otherwise use controller B.
Is there a way to do that?
I found this similar question Spring MVC - Request mapping, two urls with two different parameters
where someone has mentioned "use one method in a misc controller that dispatches to the different controllers (which are injected) depending on the request param." , how do I implement that?
Controller 1
#RequestMapping(value= {"/myurl"}, params = { "a" })
public ModelAndView handleMyURL()
Controller 2
#RequestMapping(value= {"/myurl"}, params = { "b" })
public ModelAndView handleMyURL()
Take a look at chapter 4 of this post for more detail
#Controller
#RequestMapping(value= {"/myurl"})
public TestController{
#Autoware
private TestAController testAController;
#Autoware
private TestBController testBController;
public void myMethod(String a){
if(a.equals("1"){
testAController.foo(a);
}else{
testBController.foo(a);
}
}
}
#Controller
#RequestMapping(value= {"/myurl1"})
public class TestAController{
public void foo(String a){
...
}
}
#Controller
#RequestMapping(value= {"/myurl2"})
public class TestBController{
public void foo(String a){
...
}
}
I did Google a lot to find my problem but I couldn't and sorry If this question already on the stack overflow because I have not find it.
First let take a look into the code
#Controller
public class Controller1 {
#RequestMapping(value = "URL", method = RequestMethod.GET)
public ModelAndView methodHandler(Parameters) {
}
public int calculation(int i){
//Some Calcucation
return i;
}
}
and second controller is
#Controller
public class Controller2 {
#RequestMapping(value = "URL", method = RequestMethod.GET)
public ModelAndView methodHandler(Parameters) {
//In this I want to call the calculation(1) method of controller1.
}
}
My question is that is there any way to call the method of calculation() of controler1 in to controller2. But remember I don't want to make method static in controller1.Is there anyway to call it without make it static?
Thanks
Yasir
You should create service bean for example in configuration file (or use # one of the annotaions) and inject it into controller. For example ()
#Configuration
public class MyConfig {
#Bean
public MyService myService(){
return new MyService();
}
}
#Controller
public class Controller1 {
#Autowire
private MyService myService;
#RequestMapping(value = "URL", method = RequestMethod.GET)
public ModelAndView First(Parameters) {
myService.calculation();
}
}
#Controller
public class Controller2 {
#Autowire
private MyBean myBean;
#RequestMapping(value = "URL", method = RequestMethod.GET)
public ModelAndView First(Parameters) {
myService.calculation();
}
}
Your controllers should not call each other. If there is a logic which needs to be used by both controllers, it is much better to put that into separate bean, which will be used by both controllers. Then you can simply inject that bean to whicheveer controller neccessary. Try not to put any business logic to controllers, try tu put it to specialized class instead which will be web independent if possible and will accept web agnostic business data as user email, account number etc. No http request or response. This way your class with actual logic is reusable and can be unit tested much more easily. Also, if there is state, it should be contained in your classes outside controllers. Controllers should be stateless and not contail any state at all.
When using MVC pattern and you are deciding where to put your logic, you should separate business logic into model and into controllers you should put only logic regarding user interaction, as explained in this stack overflow post.
I have used the Spring MVC. I set the Session Attribute value like
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String initHome(Model model) {
if (!model.containsAttribute("clientObject")) {
model.addAttribute("clientObject", createDefaultClient());
}
return "homeMenu";
}
It is working fine if i click the home menu url(/home). but if i did not go the
home means it says error as 'session attribute clientObject is required'
so i decided to set sessionattibutes in constructor of controller
#Autowired
public MyController(Model model) {
if (!model.containsAttribute("clientObject")) {
model.addAttribute("clientObject", createDefaultClient());
}
}
it also says error
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myController'
I tried to set using the RequestMapping also like
#RequestMapping(value = "/", method = RequestMethod.GET)
public void initController(Model model) {
if (!model.containsAttribute("clientObject")) {
model.addAttribute("clientObject", createDefaultClient());
}
}
this method is also not called intially
my cointroller look like
#RequestMapping("/sample")
public class MyController {
..
..
is it possible to set the sessionAttribute value in the constructor of controller? or any other way to set the session Attribute initially?
Thanks in advance for your help.
Assuming your createDefaultClient is in the controller add a #ModelAttribute annotation to it.
#ModelAttribute("clientObject")
public ClientObject createDefaultClient() { ... }
This method will be called before any request handling method (as explained in the reference guide)
If you combine that with a #SessionAttribute annotation on your class (which you might already have). You should be able to achieve what you want.
In your request handling methods (methods annotated with #RequestMapping) you can now simply inject the client object as a method argument.
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String initHome(#ModelAttribute("clientObject") ClientObject clientObject) {
// Do something with the clientObject
return "homeMenu";
}
This will only work consistenly within the same controller, so if you need the ClientObject to be used somewhere else (another controller for instance), this isn't going to work (nor is #SessionAttributes designed for that).