Liferay 7.2 Api Rest Session parameter - rest

I have Liferay 7.2.
I created a module rest.
It is possibile to save a variable in session ad use it in other method?
My idea of code is:
#GET
#Path("/save/paramt")
public String jsonSaveParamRequest() throws Exception {
String json = "xx";
//SAVE IN SESSION json
return "ok";
}
#GET
#Path("/get/paramt")
public String jsonGetParamRequest() throws Exception {
String xx= SESSION VARIABLE json
return xx;
}

Saving state in a HTTP session in a REST API is not recommended and should be avoided. Please refer to the discussions here SO:how-to-understand-restful-api-is-stateless.
Technically, I guess this is possible as you can inject the HttpServletRequest as a method param via #Context HttpServletRequest request to your annotated method and use getSession(). But I am not sure if you can rely on that.

Related

Dumping bad requests

I have a service implemented with Dropwizard and I need to dump incorrect requests somewhere.
I saw that there is a possibility to customise the error message by registering ExceptionMapper<JerseyViolationException>. But I need to have the complete request (headers, body) and not only ConstraintViolations.
You can inject ContainerRequest into the ExceptionMapper. You need to inject it as a javax.inject.Provider though, so that you can lazily retrieve it. Otherwise you will run into scoping problems.
#Provider
public class Mapper implements ExceptionMapper<ConstraintViolationException> {
#Inject
private javax.inject.Provider<ContainerRequest> requestProvider;
#Override
public Response toResponse(ConstraintViolationException ex) {
ContainerRequest request = requestProvider.get();
}
}
(This also works with constructor argument injection instead of field injection.)
In the ContainerRequest, you can get headers with getHeaderString() or getHeaders(). If you want to get the body, you need to do a little hack because the entity stream is already read by Jersey by the time the mapper is reached. So we need to implement a ContainerRequestFilter to buffer the entity.
public class EntityBufferingFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
ContainerRequest request = (ContainerRequest) containerRequestContext;
request.bufferEntity();
}
}
You might not want this filter to be called for all requests (for performance reasons), so you might want to use a DynamicFeature to register the filter just on methods that use bean validation (or use Name Binding).
Once you have this filter registered, you can read the body using ContainerRequest#readEntity(Class). You use this method just like you would on the client side with Response#readEntity(). So for the class, if you want to keep it generic, you can use String.class or InputStream.class and convert the InputStream to a String.
ContainerRequest request = requestProvider.get();
String body = request.readEntity(String.class);

#BeanParam gives exception A message body reader for Java class was not found

I am trying to make a jersey based web service. In this if i take input params using #FormParam it works fine:
#POST
#Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, "application/x-www-form-urlencoded"})
#Path("/registeruser")
public Response registerUser(#FormParam ("email") String email,#FormParam ("name") String name ){
System.out.println("Inside register device");
System.out.println("registered" + email);
return null;
}
but when I try using #BeanParam it does not works and gives me an exception
#POST
#Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, "application/x-www-form-urlencoded"})
#Path("/registeruser")
public Response registerUser(#BeanParam UserForm userForm ){
System.out.println("Inside register device");
service.registerUser(userForm);
System.out.println("registered" + userForm.getEmail());
return null;
}
A message body reader for Java class com.stc.dms.forms.UserForm, and Java type class com.stc.dms.forms.UserForm, and MIME media type application/octet-stream was not found.
You don't need to use #BeanParam to pass an object as input. Just pass it like this :
#POST
#Path("register")
#Consumes(MediaType.APPLICATION_JSON)
public Response registerUser(UserForm dto) {
// ...
}
Just make sure to include the libraries for producing/consuming json. If the client is in javascript you don't need anything else (just use JSON.stringify() on your form object), for the server add some json libraries such as Jackson
EDIT :
If you want to stick with #BeanParam, take a look at this tutorial here. Basically it seems that you don't need to specify the mediatype, as Jersey will handle that for you.

How can I get parameter from the URL in Websphere commerce CmdImpl class

Is there any way to get url parameter in websphere commerce CmdImpl class.
I am trying like this
SmartDataBeanImpl bean = new SmartDataBeanImpl();
HttpServletRequest request = bean.getHttpRequest();
String currencyId = request.getParameter("currencyId");
But I got the NullPointer exception at 3rd Line
Given the assumption that you are working with a controller command then you should access the URL parameters like this:
public void setRequestProperties(TypedProperty pRequestProperties) {
String currencyId = pRequestProperties.getString("currencyId", "");
}
requestProperties.getString("URL", null)
You would see this in most of the OOB controller commands in the validateParameters() method.

Xpage REST service control and service bean

I am trying to implement REST Service using XPage REST Service Control. I have opted for "customRESTService".
I would like to emit JSON when this service is requested. I can write logic in Server Side Java Script.
But I noticed that this customRESTService also supports "serviceBean", meaning I can write whole logic in pure JAVA.
I have given below code of the bean. I have declared it in faces-config.xml as well. But it throws exception while rendering. Has anyone used "serviceBean" in customRESTService?
I appreciate any help!! Thanks!!
public class GetApproverJSON{
public GetApproverJSON(){
System.out.println("Instantiating Bean");
}
public String doGet() throws NotesException{
JSONObject mainObj = new JSONObject();;
JSONObject itemObj;
try{
mainObj.put("label", "name");
mainObj.put("identifier", "abbr");
itemObj = new JSONObject();
itemObj.put("name", "");
itemObj.put("abbr", "");
mainObj.accumulate("items", itemObj);
return mainObj.toString();
}catch(Exception e){
System.out.println("Exception occured while generating JSON ");
e.printStackTrace();
return mainObj.toString();
}finally{
}
}
Error :
com.ibm.domino.services.ServiceException: Error while rendering service
at com.ibm.xsp.extlib.component.rest.CustomService$ScriptServiceEngine.renderService(CustomService.java:304)
at com.ibm.domino.services.HttpServiceEngine.processRequest(HttpServiceEngine.java:167)
at com.ibm.xsp.extlib.component.rest.UIBaseRestService._processAjaxRequest(UIBaseRestService.java:252)
at com.ibm.xsp.extlib.component.rest.UIBaseRestService.processAjaxRequest(UIBaseRestService.java:229)
at com.ibm.xsp.util.AjaxUtilEx.renderAjaxPartialLifecycle(AjaxUtilEx.java:206)
at com.ibm.xsp.webapp.FacesServletEx.renderAjaxPartial(FacesServletEx.java:221)
at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:166)
at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:137)
at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1267)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:847)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1251)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:598)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:421)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:341)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:297)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
Caused by: com.ibm.xsp.FacesExceptionEx: Bean getApproverJSON is not a CustomServiceBean
at com.ibm.xsp.extlib.component.rest.CustomService.findBeanInstance(CustomService.java:226)
at com.ibm.xsp.extlib.component.rest.CustomService$ScriptServiceEngine.renderService(CustomService.java:255)
... 20 more
You need to change your code to:
public class GetApproverJSON{ ...}
to:
public class GetApproverJSON extends CustomServiceBean {
#Override
public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
HttpServletRequest request = engine.getHttpRequest();
HttpServletResponse response = engine.getHttpResponse();
response.setHeader("Content-Type", "application/json; charset=UTF-8");
// Here goes your code, get the response writer or stream
}
since that's the interface the REST service is expecting. You will need to implement just renderService. You can get the method (GET, POST etc.) from the request object
I've never used the service bean before, I usually create my own parser with a static doGet method very similar to yours and in the doGet property of the custom REST service make a call to the static doGet method I create. But I think (I'm probably wrong on this count) if you use the service bean it has to be an entire servlet like if you wrote your own actual REST Service, and not just the parser portion.
I've created quite a few of the parsers and have found that a list of maps:
List>
is usually the best approach for building the initial data. I then loop through the list to build my JSON. In the Extension Library there is a class called JsonWriter which makes it very easy to build a JSON Object. Use the JsonWriter like:
StringWriter sw = new StringWriter();
JsonWriter jw = new JsonWriter(sw);
jw.startObject();
jw.startProperty("SomeProperty");
jw.outStringLiteral("SomeValue");
jw.endProperty();
jw.endObject();
return sw.toString();
For a full on example you can take a look at the REST service I built for my JQuery FullCalendar demo. While none of the methods are static (I need to track a couple of properties) you should get the basic idea. But what kicks the whole thing off is a call to the writeJson() method. That is invoked in this custom control.
Those examples should get you going on building your own custom JSON parser and emitting that JSON back to your application.

Jersey : How to send /pass Custom DTO to a Service class in Jersey

I am using Jersey Framework for developing my Webservices. I have a DTO object named UserInfo with setters and getters inside it. I am setting this DTO value initially when the user logs in. How can I pass this user-specific DTO to a Jersey service class?
I have tried setting them inside MultivaluedMap and Form but I was out of luck making it work.
This is my code :
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("queryTerm", "userdto");
Form f = new Form();
f.add("name", "1001D");
And this is the way I am trying to retrieve the Data.
public class HaiService {
#GET
#Produces("application/json")
#Consumes("application/json")
public String sayPlainTextHello(#Context UriInfo ui) {
MultivaluedMap queryParams=ui.getQueryParameters();
Iterator it=queryParams.keySet().iterator();
String theKey=null;
String returnString="";
while(it.hasNext()) {
theKey=(String)it.next();
System.out.println(queryParams.getFirst(theKey));
}
System.out.println("I am called");
return "Hi";
}
But I was out of luck. Typically my requirement is to store user-specific data on logon, and then retrive that inside the service class.
I am avoiding storing data in session because a user might login with multiple ID's under one browser, which produces the same session id, and there is a chance of data being overwritten for the first logged in user.