In Play!, I want to log something after I executed a controller action, using the #Finally annotation. However, I need some data from the database I sent to my view. Is it possible to access this data in the #Finally annotated method?
This is the method in particular:
#Finally
private static void logSomething() {
//System.out.println("User: " + u.first_name);
System.out.println(response);
for (String key : response.headers.keySet()) {
System.out.println(key);
}
}
How can I pass parameters to this? If I put a parameter in the definition, it's always null (cause how should this method even know what data to pass?).. so is it possible?
If you sent it to your view, then it will be available from the renederArgs map.
So, assuming you called your render method in some way like this...
User user = User.findById(someId);
render(user);
Then you should be able to access it in renderArgs as follows
User user = (User)renderArgs.get("user");
Related
I have a class API, where you set and get the info you need to later be used on a API call
I want to make it easier to the next person who's gonna use this.
So instead of doing this:
api.addURL("urltorequesttoken");
api.addHeader("client_id","sdfsfsdfsd")
.addHeader("client_secret","sdfsdfsfsfd")
.addHeader("grant_type","client_credentials")
.addHeader("scope","READ");
api.addBody("bodyToSend")
I want to do this:
String URL = "";
URL = "put your URL here";
So I pass the URL and other variables as a parameter to another method where I will be doing what I did in the first block of code,so they don't need to know about the API class and its methods, but I dont know how to handle the hashmap, how can I do that user friendly? and then pass that as a parameter, also, what type of parameters should the methods receiving this info have? (Map<String key, String value>) or (String key, String value)?
EDIT(ADD):
So there's a class that a DEV is going to create, let's call it CreateToken
, so that class currently has:
api.addURL("urltorequesttoken");
api.addHeader("client_id","sdfsfsdfsd")
.addHeader("client_secret","sdfsdfsfsfd")
.addHeader("grant_type","client_credentials")
.addHeader("scope","READ");
api.addBody("bodyToSend")
There's another class called BASE, where Im doing the core services, in order for this to be easier for the person when they create their class, I dont want to have that block of code on their class, but instead, on mine, so in their class all they have to do is set the URL, headers and body(for POST method), so instead of this:
api.addURL("urltorequesttoken");
they will do:
URL = "urltorequesttoken";
and there's a method on their class to send me this or for me to get it i,e.
fillAPICallInfo(URL, headers, body);
I will receive that on the BASE class, but I dont know how to handle the Map variables, don't know how to make it easy for the DEV so they just put the key and value, and how do I receive that on my class (as a Map or as Strings)?
So you simply can pass a Map<String, String> as parameter:
public void fillAPICallInfo(String url, Map<String, String> headers, String body) {
// Assuming there is an instance of class DEV named api available
api.addURL(url);
headers.forEach((h, v) -> api.addHeader(h, v));
api.addBody(body);
}
Problem:
I currently have a grid that displays content of type SomeModel.
When I click an entry of that Grid I would like to navigate to a view that takes an object as its input to display the entries content.
Implementation:
To achive this behaviour I created a DetailLayout like this:
public DetailLayout extends FlexLayout implements HasUrlParameter<SomeModel>{
/* skipped some details */
#Override
public void setParameter(BeforeEvent event, Host parameter) {
/* This is where I expected to be able to handle the object */
}
}
From within the Grid I tried to navigate like this:
addSelectionListener((event) -> {
event.getFirstSelectedItem().ifPresent(somemodel -> {
getUI().ifPresent(ui -> {
ui.navigate(DetailLayout.class, somemodel);
});
});
});
But unfortunately this behaviour is not supported by Vaadin even tho its syntax is perfectly fine.
Question:
Do you know of another way to pass an object while navigation or did I miss a certain part of the official documentation documentation ?
Thank you in advance
Key-Value collection
As discussed in the comments on the other Answer, if you do not wish to expose the ID value as part of the URL, then work behind the scenes by using the key-value collection provided by Vaadin.
Vaadin actually provides key-value collections at three levels of scope:
ContextYour entire web-app at runtime
SessionEach user
UIEach web browser window/tab, as Vaadin supports multi-window web-apps
The app-wide key-value collection is available on the VaadinContext, via getAttribute & setAttribute methods.
VaadinService.getCurrent().getContext().setAttribute( key , value ) ;
The per-user key-value collection is available on the VaadinSession, via getAttribute & setAttribute methods.
VaadinSession.getCurrent().setAttribute( key , value ) ;
➥ The per-browser-window/tab collection (what you want for your needs in this Question) is not quite so readily available. You have to go through an indirect step. On the ComponentUtil class, call setData & getData methods. In addition to passing your key and your value, pass the current UI object.
Component c = UI.getCurrent() ;
String key = "com.example.acmeapp.selectedProductId" ;
Object value = productId ;
ComponentUtil.setData( c , key , value ) ;
Please vote for my ticket # 6287, a feature-request to add setAttribute/getAttribute methods on UI class, to match those of VaadinSession and VaadinContext.
Instead of giving the whole somemodel object as parameter of navigate(), you can pass its id
ui.navigate(DetailLayout.class, somemodel.getId());
And in the DetailLayout.setParameter() you can load the somemodel by its id
#Override
public void setParameter(BeforeEvent beforeEvent, Long someModelId) {
if(someModelId == null){
throw new SomeModelNotFoundException("No SomeModel was provided");
}
SomeModel someModel = someModelService.findById(someModelId);
if(someModel == null){
throw new SomeModelNotFoundException("There is no SomeModel with id "+someModelId);
}
// use someModel here as you wish. probably use it for a binder?
}
If you are using Spring with Vaadin Flow then you could create a #UIScoped bean and add your own fields storing state related to the current browser window/tab. The bean will be available as long as the UI is present.
I overwrote the public Action onRequest(final Http.Request request, Method method) method to check that the mandatory http headers are passed in and valid, i.e.: I extract the apiKey (and other things) and make sure that these are valid (that there's data associated with the apiKey). Then I call return super.onRequest(request, method); and I end up in my controller where I once again have to extract the apiKey and get the associated data from the DB.
Is there a way to pass in the data to my controller's method (for instance: public static Result addUser() ).
Thank you.
I know this question is for Java, but I work with Play in Scala, and this question is more related to Play then it is to Java
In Scala I am able to extend WrappedRequest to make my own custom request type, that has instance variables I want to access in my controller:
// Scala code
case class MyRequest[A](request: Request[A]) extends WrappedRequest(request) {
// This is a public instance variable
val apiKey = request.headers.get("Authorization)
}
Then later on in my controller I can access the action object which now has the type of MyRequest:
// Scala code
def foobar(action: MyRequest[AnyContent]) = Action {
// Do something with the api key
val apiKey = action.apiKey
// Send back a response
Ok("foobar")
}
In Java it looks like you can do something similar using a Wrapped Context
I have a RemoteServiceServlet class implements several services (methods).
All the methods need to check the session and get the corresponding user info before doing anything. Since the class have more than 20 service methods, doing so in every service is a nightmare. Is there a way to run some session checking method automatically for all the incoming requests? Or how can I solve this problem?
Here is an example pseudo-code for my situation.
public class OnboardingServiceImpl extends RemoteServiceServlet implements OnboardingService {
private String checkSessionAndGetUser(){...}
public void service1(){
// check session
// get user and do something based on the user data
}
public void service2(){
// check session
// get user and do something based on the user data
}
public void service3(){
// check session
// get user and do something based on the user data
}
...
public void service20(){
// check session
// get user and do something based on the user data
}
}
As you can see, service1, service2, ..., service 20 all need to get the user info based on the session, but I do not want to repeat writing the code for every service. Any help will be appreciated.
I'd suggest to override processCall(RPCRequest rpcRequest)
#Override
public String processCall(RPCRequest rpcRequest) throws SerializationException {
//your checks here, in case of error:
//return RPC.encodeResponseForFailedRequest(null, new Exception("Invalid session"));
// note that you'll have to use a serializable exception type here.
return super.processCall(rpcRequest);
}
RemoteServletServlet's doPost is final, but not service, so you can put your code there.
…or use a servlet filter.
This will however be done outside the "RPC" (before the request is even decoded), so response cannot just be a "throw exception and have it passed to onFailure on client side".
For that, you'll have to either use aspect-oriented programming (such as AspectJ) to "inject" code into all your methods, or call an init method at the beginning of each method (you'll keep repeating the code, but that could possibly be reduced to a one-liner).
I am new to Jersey, and I discovered that we can define our own parameter types to handle other types than string, as dates or boolean for instance.
I will work with an ORM to store the data in a database, so that I will be able to map an identifier to an instance of a class, let's say to a User.
Is it a good practise to define a param class which would handle the user id given in parameter (path or query for instance), and return the instance of User corresponding to the id?
If your param is directly mappable to a primitive type then there's no need to define your own. It sounds like you want to accept a user ID as a param, which is likely to be a long, int or String. All of these are automatically mapped.
For example;
#Path("/")
public class UserService {
#GET
#Produces(MediaType.APPLICATION_XML)
#Path("/{id}")
public User getUser(#PathParam("id") String id) {
//Your implementation here
}
}
Well, lets take some example:
stackoverflow.com/users/1235336/
Here we have the path with usedId in it. And if we proceed the link (execute a GET request), we will get the some user enity in response.
So defining a user id as a path parameter and returning some user instance is kind of normal practice.