How do I access the HTTP request? - rest

Say normally I have a REST method in Java
#POST
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public String showTime(#FormParam("username") String userName) {
:
:
:
}
which is fine. However, I'm wondering is there a way I can access the full HTTP request with Jersey such as
#POST
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public String showTime(#FormParam("username") String userName,#XXXXXX String httpRequest) {
:
:
:
}
where some annotation would give me the full HTTP request to store in a variable. I have tried using #POST but it doesn't seem to work. Any suggestions?

You can use the #Context annotation:
#POST
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public String showTime(
#FormParam("username") String userName,
#Context HttpServletRequest httpRequest
) {
// The method body
}

If you want to get the request body, you could use the tip lined out in this post: How to get full REST request body using Jersey?
If you need to know more about the request itself, you could try the #Context annotation as mentioned by sdorra.

I wrote a helper function to address this. Simply extracts request headers and places them in a map.
private Map<String, String> extractHeaders(HttpServletRequest httpServletRequest) {
Map<String, String> map = new HashMap<>();
Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
while (headerNames.hasMoreElements()) {
String header = headerNames.nextElement();
map.put(header, httpServletRequest.getHeader(header));
}
return map;
}

Related

Reading the contents of a body of a POST request in java (using REST)

Suppose I make a POST request using POSTMAN and have a body in json format. I want to read the contents of body and pass it in a method. How to do it ?
I can see that there is #QueryParam, #PathParam, #HeaderParam etc annotation are used to read the parameters. I don't get how to read body.
say body is
{
"param1":"value1",
"param2":"value2",
"param3":"value3",
}
ServerSide java code:
#POST
#Path("/myresource")
public Response addParams( String param1, String param2, String param3)
{
do somthing.
}
So I wanted this param1,param2,parmam3 values to be read from requestbody. Is it possible ?
Define a class like:
public class Foo {
String param1;
String param2;
String param3;
// Default constructor, getters and setters
}
Then use it as follows:
#POST
#Path("/myresource")
#Consumes(MediaType.APPLICATION_JSON)
public Response addParams(Foo params) {
String param1 = params.getParam1();
String param2 = params.getParam2();
String param3 = params.getParam3();
...
}
Alternatively, use a Map<String, String>:
#POST
#Path("/myresource")
#Consumes(MediaType.APPLICATION_JSON)
public Response addParams(Map<String, String> params) {
String param1 = params.get("param1");
String param2 = params.get("param2");
String param3 = params.get("param3");
...
}
Just ensure that you have a JSON parser such as Jackson or MOXy configured in your application.
Don't know which Java framework you use, but you could declare a #RequestBody parameter in your method and "map" it to a POJO that will correspond to the incoming JSON (just like #Smutje said in the comment).
For example, in Spring, we do it like this,
#PostMapping(value = "/example",
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity postExample(#RequestBody ExamplePOJO examplePOJO) {
// Do something
}

Combining verbs in Apache CXF JAX-RS

We would usually define POST and PUT verbs as different service APIs.
#POST
#Path("/getbook")
#Produces({"application/xml","application/json"})
#Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})
public Response getBucket() {
... }
#PUT
#Path("/getbook/{name}")
#Produces({"application/xml","application/json"})
#Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})
public Response getBucket(#PathParam("name") String name) {
... }
Would there be a way to combine these verbs into a single method - and then drive different logic based on the type of the verb ?
Hypothetically
#POST
#PUT
#Path("/getbook/{name}")
#Produces({"application/xml","application/json"})
#Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})
public Response getBucket(#PathParam("name") String name) {
if(verb=POST){
... }
else{
}
}
You may try like this using MessageContext. You need the context injected into the service method like below for updateCustomer method and then you can check for the method type as you like (here I am checking for PUT):
#Path("/customer")
public class CustomerService {
#Context
private org.apache.cxf.jaxrs.ext.MessageContext mc;
#PUT
public Response updateCustomer(#Context MessageContext context, Customer c) {
HttpServletRequest request = context.getHttpServletRequest();
boolean isPut = "PUT".equals(request.getMethod());
}
}

How to get the url of called method resteasy

I making one Rest Service with Restaeasy (java) that have to return the same URL that was called but with one new string
Example Call service:
Post => mybase/myservice/somewrite with some JSON
| Reponse => mybase/myservice/somewrite/123456
So i want to make the mybase/myservice/somewrite url with one generic logic, because if i put String returnURL="mybase/myservice/somewrite"; and i change for example the name of mybase the reponse will not be good
I want somthing like this
someLogicService(JSON);
id=getId();
URL=getContextCallURL();
return URL+\/+id;
But i dont know if this is possible to do it, and less how to do it
You could also inject an instance of type UriInfo using the annotation Context within your resource, as described below:
#Context
private UriInfo uriInfo;
#POST
#Path("/")
#Consumes(MediaType.APPLICATION_JSON)
public Response makeContact(Contact contact) {
String requestUri = uriInfo.getRequestUri();
(...)
}
Hope it helps you,
Thierry
I found the answer to my problem, i put inject with #context the httpRequest to my function and call absolutPath :
#POST
#Path("/")
#Consumes(MediaType.APPLICATION_JSON)
public Response makeContact(Contact contact, #Context HttpRequest request) {
return Response.ok().header("location", request.getUri().getAbsolutePath().getPath() + contactService.makeContact(contactJSON)).build();
}

How to use #FormParam if form elements are dynamically created

Since html form elements are dynamically created in this application, the number of elements are not known. How does one obtain element information using #FormParam annotation? For example, the below code obtains information for two form elements:
#POST
#Path("/newpage")
#Produces("text/html")
public String func(#FormParam("element1") String firstElement,
#FormParam("element2") String secondElement) throws IOException
{
// your code goes here
}
This is not possible as we don't know the number of elements.
I can't think of a way to do this using #FormParam but you can use #Context to access the HttpServletRequest (which references a map of all form parameters):
// you can make this a member of the Resource class and access within the Resource methods
#Context
private HttpServletRequest request;
#POST
#Path("/newpage")
#Produces("text/html")
public String func() throws IOException
{
// retrieve the map of all form parameters (regardless of how many there are)
final Map<String, String[]> params = request.getParameterMap();
// now you can iterate over the key set and process each field as necessary
for(String fieldName : params.keySet())
{
String[] fieldValues = params.get(fieldName);
// your code goes here
}
}
The correct answer is actually to use a MultivaluedMap parameter to capture the body (tested using Jersey):
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.TEXT_HTML)
public String post(MultivaluedMap<String, String> formParams)
{
... iterate over formParams at will

How to construct a URI path according to the formparams in REST jersey

First read this .
Now i had known how to construct it grammatically...but how to ACCEPT a forms parameters,PROCESS it and CONSTRUCT a URI accordingly is still unkown !!
My form :
#POST
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void newUser(
#FormParam("uname") String uname,
#FormParam("password") String password,
#Context HttpServletResponse servletResponse
) throws IOException {
User u = new User(uname,password);
User.userdata.put(uname,password);
}
i will recieve it like this :
#Path("/user/{uname}")
#PUT
#Consumes("text/plain")
public void putUser(#PathParam("uname") String uname, String password) {
// ..
}
But the path
http://mysite/users/abc
for a user "abc" doesn't seem to exists..
apache is giving error 405 method not allowed...
I am asking how to construct that path by processing parameters in my form...