Prevent Calling one method before calling another - java

Can you please share me the standard method, if any to prevent one method call before the client call another. For example: I have the following two methods in my controller
#RequestMapping(value = “/save”, method = RequestMethod.PUT)
#ResponseBody
public String save(string temp){
return service.update(temp);
}
#RequestMapping(value = “/save/confirm”, method = RequestMethod.PUT)
#ResponseBody
public String ValidateInfo(string temp){
return service.update(temp);
}
So the question is what is the standard way to prevent the client side from calling the save method before calling the validateInfo method using REST API features. Assuming both methods do serious of stuff in the server side.

The client, which might be a different piece of software that you don't control, can make any call at any time. So you can't really prevent a client from making calls. This suggests that your design is a bit flawed.
I would suggest validating the user input as part of the save method - this is usually more secure and robust. If the validation fails, you should consider how you want to notify the client. For example, you could return an error message.

You can return a token from method1 which needs to supplied as parameter to method2..In this way you can make sure that method2 is always called after method1

Related

Rest Service method mapping [Java Spring]

This is my first try at writting service from scratch. I'm using RestController and Java Spring to create a service which generates pdf based on parameters which are passed when calling the service. Service is called with one parameter, but can be called with two different variables (one is registry number and the other is identificator) and depending on which one of those two is passed, service generates the same JSON but different service is called in background of my program (one call works with IDN and one works with regNum).
So far I have this:
#RequestMapping(value = "/generatePdf/{idn}", method = RequestMethod.GET, produces = "application/pdf")
public String generatePdf(#PathVariable String idn) {
//logic
}
My question is this. What is the best solution for this problem?
Do I make separate method with different name and mapping?
Should I create a flag which checks which type od data is sent? Or, something third, feel free to suggest.
I would recommend you to create separate method instead of adding the additional flag:
API will be more readable and understandable, eg: GET /pdfByIdn/{idn} and GET /pdfByRN/{rn}
Easy to add additional cases, without modification of existing methods
Its make more sense to use separate service classes to different approaches to generate PDF's
#RequestMapping(value = "/generatePdf/{idn}/{rgn}", method =
RequestMethod.GET,
produces = "application/pdf")
public String generatePdf(#PathVariable(required = false) String idn,
#PathVariable(required = false) String rgn)
{
if(idn.equals(null){
//logic
}else {
//logic
}
}

how to return value as response in #before, with out moving to the controller (using AOP)

I'm using AOP concept and the dispatcher sends the call to before advice method. In that, how to return value in before advice method with out getting into controller?
public Object cache(JoinPoint jointPoint, RedisCache redisCache) throws Throwable{
String data = getRedisService().getValue(redisKey);
if(data != null){return "hi";}
}
before advice:
Before advice runs before a matched method execution
around advice
It has the opportunity to do work both before and after the method
executes, and to determine when, how, and even if, the method actually
gets to execute at all

using multiple modelAttributes to receive 2 objects from JSP

I am working on a Spring-MVC application in which there are 2 parts. It is basically a note taking application with 2 modes, one is groupMode and other is personalMode. Now they both have their different dao's, serviceImpl in the backend, but they are in one controller view.
I have a boolean value to set, to know which mode is the user currently in, to perform CRUD operations in the specific database table. Now As both group modes are personal modes are in the same view, I have to make my methods so they can accept objects from either of the mode. Does spring support accepting only one object even if I declare 2 in model attribute. Here is the example of what I want to achieve :
#RequestMapping(value = "/section/add", method = RequestMethod.POST)
public
#ResponseBody
boolean addSection(#ModelAttribute("section") Section section, #ModelAttribute("groupsection") GroupSection groupSection,Model model) {
if(boolean == true){
this.groupSectionService.addGroupSection(groupSection);
model.addAttribute("groupsection", new GroupSection());
} else{
this.sectionService.addSection(section);
model.addAttribute("section", new Section());
}
return true;
}
Is this possible, I will always be sending one object from the front-end. Thanks a lot. Any pointers or suggestions are welcome.
Whenever there is such a if-statement that "split" the complete controller method, like yours, I have the feeling that one controller method should been replaced by two methods, one for each case.
The easiest, and most straight forward solution would been using two different URLs.
But maybe you have some reason for using the same URL, then I would have two different controller methods with the same URL but a different params Attribute in #RequestMapping
#RequestMapping(value = "/section/add",
method = RequestMethod.POST
params="createGroupSection=false")
#ResponseBody
public boolean addSection(#ModelAttribute("section") Section section) {...}
#RequestMapping(value = "/section/add",
method = RequestMethod.POST
params="createGroupSection=true")
#ResponseBody
public boolean addGroupSection(#ModelAttribute("section") Section section) {...}

How to find number of times static function is called Mockito

I am having a function like the following.
public String getDecodedToken() throws UnsupportedEncodingException {
if (token == null) {
String token = ClassContainingStatic
.findString("static");
this.token = new String(Base64.decodeBase64(token), "UTF-8");
}
return token;
}
To test the function, I do not want to mock the ClassContainingStatic class because it will render the test useless. Rather I would like to see that if the call happened to ClassContainingStatic.findString("static") without mocking the object. Is there a way to achieve number of function call made to the real object?
Certainly possible with a bit of refactoring. If you extract the call to the static class in a separate method:
public String getDecodedToken() throws UnsupportedEncodingException{
if( token == null ){
token = createToken();
}
return token;
}
String createToken() throws UnsupportedEncodingException{
String token = ClassContainingStatic.findString("static");
return new String( Base64.decodeBase64(token), "UTF-8" );
}
Now you can create a mock or spy, and simply verify whether the method is called.
ClassUnderTest spy = Mockito.spy( new ClassUnderTest() );
String token = spy.getDecodedToken();
Mockito.verify( spy ).createToken();
I assumed the "static" string is fixed. If not, pass it as a parameter to the createToken class, and then you can adjust the verify accordingly.
I might have made a mistake in the Mockito syntax, but the general idea should be clear. Only drawback is that you need to create a package visible/protected (or even public if you want, but generally that is not the case) method so that the verify call can be made.
The basic thing you need here is called a spy in Mockito language.
While a mock is a completely new object, a spy wraps an existing instance and forwards calls to its methods to the original object by default, while at the same time supports mocking of method calls or verifying of calls.
But you have another challenge: the method you want to verify seems to be a static method. With Mockito you can't mock static methods. You have two basic options:
Refactor so that the method is no longer static and you provide the object which hosts the method on as a parameter to the constructor. This parameter then can be a mock or spy.
Use PowerMock to mock static methods. I would only accept the usage of PowerMock in legacy projects, where one needs to create tests with as little refactorng as possible. PowerMock is poerful yet clumsy, slow and prone to causing problems down the road, e.g. by creating lots of classes on the fly resulting in PermGen issues.

Play Framework 2 - Call Web Service and return an object

I have a model which I want to populate with details from a web service. I'd like to do this asynchronously so as not to block a server thread. Let's pretend it's a login service.
Now what I want to do is fire a request to the remote server and ultimately return a User model object. So the method signature would look something like this:
public static User loginUser(String username, String password) {
I understand that to make an asynchronous call to a web service I should use a Promise:
Promise<WS.Response> wsPromise = WS.url("http://myserver.com/login")
.setContentType("application/json; charset=utf-8")
.post("... the username and password ...");
Which doesn't start the request yet. I could call get() on this object to make a blocking call to the service. This works.
To do this asynchronously, I thought I'd need to map this and somehow execute it.
Promise<User> resultPromise = wsPromise.map(new F.Function<WS.Response, User>() {
#Override
public User apply(WS.Response response) throws Throwable {
System.out.println(response.getBody());
return new User(... based on something extracted from the returned JSON ...);
}
});
Now how do I trigger this operation? If I call get() on the resultPromise, it makes the call but eventually fires a Timeout Exception. I can't use the async(...) method because that only returns me a Result.
Looking at other examples (https://github.com/jroper/play-promise-presentation/blob/master/src/main/java/controllers/Application.java), this seems to be the pattern. i.e. We always want to return a Result object. However, I can't query a Result object and I have no plan to send that specific object out to the user.
In fact, those examples seem to call a web service, map the JSON result to an object and then immediately map them back to the same JSON. Not much use when I want to pass the User (in my case) back to the calling function.
To be honest, I'm a little confused with the asynchronous nature of this anyway (you probably guessed that). In particular, this is really a blocking action as we have to wait for the web service to return a response. The documentation seems to indicate that using the Promise / Future patterns will avoid this blocking.
Bottom line is: How do I map the result of a web service call back to a model object without blocking a thread in the Play Framework server?
Feel free to abuse my lack of experience of the Play Framework...
This answer might come way too late, but will post it in case someone else nowadays still wonder the same and want an answer to the question.
There are two ways to achieve this, even though both make use of the same JsonNode class:
The first one is what you were expecting: "new User( ..something...)"
In this case you can make use of JsonNode's "get" method to obtain the specific data you need to create the User object (username and email in my example since you didn't specify the required fields).
Promise<User> resultPromise = wsPromise.map(new F.Function<WS.Response, User>() {
#Override
public User apply(WS.Response response) throws Throwable {
System.out.println(response.getBody());
JsonNode json = response.asJson();
return new User(json.get("username"), json.get("email"));
}
});
The other option is in case you know the Web Service does return a valid Json representation of an User object.
Personally I think this option is way easier and relys on fromJson's method from Json class.
Promise<User> resultPromise = wsPromise.map(new F.Function<WS.Response, User>() {
#Override
public User apply(WS.Response response) throws Throwable {
System.out.println(response.getBody());
return Json.fromJson(response.asJson(), User.class);
}
});
I hope this answer can help people wondering how to do this in a easy way.
.get() or .post(...) on a WS call actually does trigger the WS call to go out. (Don't confuse WS.get() with myPromise.get()... they are quite different).
The trick to keeping this sort of design fully async is to have Promises all the way down, from the Controller response, all the way down.
To do this, you must make judicious use of the map(), flatMat(), and sequence() methods in the Promise API.
In your particular case, you use the result of the WS call inside the code that does the map() that happens when the WS call returns. That is where you use the response to actually do things.
This paradigm is easier in Scala with "for comprehensions", but it's still possible in Java with chains of nested flatMap calls ended with a map call.

Categories