Can I accept JSONObject as parameter in Rest API? - java

My code is as follows:
#Path("/test")
public class Test {
#POST
#Path("/postSomething")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public RestMessageResponse postSomething(JSONObject inputJSONObject) {
..do something
}
}
when I send a post request to the appropriate url, it doesn't reach the code.

Why would you want to do this anyway?
Just send the plain JSON in your HTTPRequest and parse it. For me, this usually looks like this:
#RequestMapping(path= "/app/syncImages", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
public ResponseEntity<?> someMethod(#RequestBody String body){
JSONObject request = new JSONObject(body);
...
}
Have you tried your code? Does it not work in some capacity?

Related

Http Post request with content type application/x-www-form-urlencoded not working in Spring

Am new to spring currently am trying to do HTTP POST request application/x-www-form-url encoded but when i keep this in my headers then spring not recognizing it and saying 415 Unsupported Media Type
for x-www-form-urlencoded
org.springframework.web.HttpMediaTypeNotSupportedException: Content
type 'application/x-www-form-urlencoded' not supported
Can any one know how to solve it? please comment me.
An example of my controller is:
#RequestMapping(
value = "/patientdetails",
method = RequestMethod.POST,
headers="Accept=application/x-www-form-urlencoded")
public #ResponseBody List<PatientProfileDto> getPatientDetails(
#RequestBody PatientProfileDto name
) {
List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
list = service.getPatient(name);
return list;
}
The problem is that when we use application/x-www-form-urlencoded, Spring doesn't understand it as a RequestBody. So, if we want to use this
we must remove the #RequestBody annotation.
Then try the following:
#RequestMapping(value = "/patientdetails", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public #ResponseBody List<PatientProfileDto> getPatientDetails(
PatientProfileDto name) {
List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
list = service.getPatient(name);
return list;
}
Note that removed the annotation #RequestBody
you should replace #RequestBody with #RequestParam, and do not accept parameters with a java entity.
Then you controller is probably like this:
#RequestMapping(value = "/patientdetails", method = RequestMethod.POST,
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public #ResponseBody List<PatientProfileDto> getPatientDetails(
#RequestParam Map<String, String> name) {
List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
...
PatientProfileDto patientProfileDto = mapToPatientProfileDto(mame);
...
list = service.getPatient(patientProfileDto);
return list;
}
The solution can be found here https://github.com/spring-projects/spring-framework/issues/22734
you can create two separate post request mappings. For example.
#PostMapping(path = "/test", consumes = "application/json")
public String test(#RequestBody User user) {
return user.toString();
}
#PostMapping(path = "/test", consumes = "application/x-www-form-urlencoded")
public String test(User user) {
return user.toString();
}
Remove #ResponseBody annotation from your use parameters in method. Like this;
#Autowired
ProjectService projectService;
#RequestMapping(path = "/add", method = RequestMethod.POST)
public ResponseEntity<Project> createNewProject(Project newProject){
Project project = projectService.save(newProject);
return new ResponseEntity<Project>(project,HttpStatus.CREATED);
}
The easiest thing to do is to set the content type of your ajax request to "application/json; charset=utf-8" and then let your API method consume JSON. Like this:
var basicInfo = JSON.stringify({
firstName: playerProfile.firstName(),
lastName: playerProfile.lastName(),
gender: playerProfile.gender(),
address: playerProfile.address(),
country: playerProfile.country(),
bio: playerProfile.bio()
});
$.ajax({
url: "http://localhost:8080/social/profile/update",
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: basicInfo,
success: function(data) {
// ...
}
});
#RequestMapping(
value = "/profile/update",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> UpdateUserProfile(
#RequestBody User usersNewDetails,
HttpServletRequest request,
HttpServletResponse response
) {
// ...
}
I guess the problem is that Spring Boot has issues submitting form data which is not JSON via ajax request.
Note: the default content type for ajax is "application/x-www-form-urlencoded".
replace contentType : "application/x-www-form-urlencoded", by dataType : "text" as wildfly 11 doesn't support mentioned contenttype..
You have to tell Spring what input content-type is supported by your service. You can do this with the "consumes" Annotation Element that corresponds to your request's "Content-Type" header.
#RequestMapping(value = "/", method = RequestMethod.POST, consumes = {"application/x-www-form-urlencoded"})
It would be helpful if you posted your code.

Calling a #POST from Jersey

I was able to get a #GET request working on jersey and the relevant code is as follows
The code for the server
#Path("/Text")
#GET
public String Hello() {
System.out.println("Text Being print");
return "Abc";
}
#POST
#Path("/post/{name}/{gender}")
public Response createDataInJSON(#PathParam("name") String data, #PathParam("gender") String data2) {
System.out.println("Post Method 1");
JSONObject obj = new JSONObject();
obj.put("Name", data);
obj.put("Gender", data2);
return Response
.status(200)
.entity(obj.toJSONString())
.build();
}
The #POST also works when the parameters are passed in the url. (as mentioned in the above code segment)
But, it doesn't work when the parameters are not sent via the url. Like the code which follows.
#POST
#Path("/post2")
public Response createDataInJSON2(#FormParam("action") String data) {
System.out.println("Post Method 2 : Data received:" + data);
JSONObject obj = new JSONObject();
obj.put("data", data);
return Response
.status(200)
.entity(obj.toJSONString())
.build();
}
May be the problem lies with the way the services are called.
//GET call (Plain Text)
System.out.println(service.path("Hello").accept(MediaType.TEXT_PLAIN).get(String.class));
//POST call (Param)
ClientResponse response = service.path("Hello/post/Dave/Male").post(ClientResponse.class);
System.out.println(response.getEntity(String.class));
//POST call (JSON)
String input = "hello";
ClientResponse response2 = service.path("Hello/post2").post(ClientResponse.class, input);
System.out.println(response2.getEntity(String.class));
Can anyone tell me what am I missing here?
Try to add a #Consumes (application/x-www-form-urlencoded) on your #POST method createDataInJSON2 and explicitly add the same mime type in your request service.path("Hello/post2").type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class, input).
Also consider that your input is just a simple string. Have a look at the class MultivaluedMap
If you have troubles with the Encoding then have a look at this post https://stackoverflow.com/a/18005711/3183976
Try this. This worked for me.
The post method:
#POST
#Path("/post2")
public Response post2(String data) {
System.out.println("Post method with File: " + data);
return Response
.status(200)
.entity(data)
.build();
}
The calling method:
ClientResponse response2 =service.path("Hello/post2").post(ClientResponse.class,"some value");
System.out.println(response2.getEntity(String.class));
Hope this helps. Peace.

How do I map JSON parameters to Jersey parameters?

I've been struggling all day, trying to bind a very simple JSON request to a method using Jersey. I can't seem to find what's wrong, any help is very appreciated.
My JSON request is as simple as this:
{"user":"xyz","pwd":"123"}
My Jersey class looks like this:
#Path("/rest")
public class JerseyService {
#POST
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
#Consumes(MediaType.APPLICATION_JSON)
#Path("authenticate.svc")
#Transactional(readOnly = true)
public Response authenticate(
String user,
String pwd) throws IOException {
Response.ResponseBuilder responseBuilder = Response.ok();
responseBuilder.entity(JsonSerializer.serialize(Status.SUCCESS));
return responseBuilder.build();
}
}
When I send the JSON request to the service as it is, the "user" parameter is set with the entire JSON request as a String (user = "{\"user\":\"xyz\",\"pwd\":\"123\"}"), while pwd remains null.
I've tried using #QueryParam, #FormParam among another annotations with both "user" and "pwd", but I can't find a way for Jersey to bind the JSON values to the Java parameters.
Any ideas of what I'm doing wrong?
Thanks!
You could use low level JSONObject or create your own Class to accept the json parameter.
The following is the example with JSONObject.
```
#Path("/rest")
public class JerseyService {
#POST
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
#Consumes(MediaType.APPLICATION_JSON)
#Path("authenticate.svc")
#Transactional(readOnly = true)
public Response authenticate(final JSONObject login) throws IOException {
System.out.println(login.getString("user"));
System.out.println(login.getString("pwd"));
//^^^^^^^^^^^^^^^^^
Response.ResponseBuilder responseBuilder = Response.ok();
responseBuilder.entity(JsonSerializer.serialize(Status.SUCCESS));
return responseBuilder.build();
}
}
```

How can I return Apache's HttpResponse within Spring's HttpServletResponse?

I have an endpoint using Spring:
#RequestMapping(value = {"/hello"}, method = RequestMethod.GET)
#ResponseBody
public String getContent(#RequestParam(value = "url", required = true) String url)
I would like this to return the exact same response I would get if I send a GET to url. I'm using the Apache library to do my GET, which returns me a CloseableHttpResponse. How do I return this response as my endpoint's response? My current code copies this response, which is not what I want. I would directly like to return the CloseableHttpResponse. The reason I want to do this is because some websites have really huge data, and I would like to avoid having to copy those in place.
#RequestMapping(value = {"/hello"}, method = RequestMethod.GET)
#ResponseBody
public String getContent(#RequestParam(value = "url", required = true) String url, HttpServletResponse response)
CloseableHttpResponse httpResponse = useApacheLibraryAndSendGetToUrl(url);
for (Header header : httpResponse.getAllHeaders()) {
response.addHeader(header.getName(), header.getValue());
}
response.setStatus(httpResponse.getStatusLine().getStatusCode());
return EntityUtils.toString(entity, "UTF-8");
}
You could write a custom HttpMessageConverter for the CloseableHttpResponse type, which would allow you to simply return #ResponseBody CloseableHttpResponse.
See Mapping the response body with the #ResponseBody annotation for details.

How to pass JSON String to Jersey Rest Web-Service with Post Request

I want to create a REST Jersey Web-Service accepting JSON string as input parameter.
Also I will use post requestand from webmethod I will return one JSON string.
How can I consume this in a HTML page using Ajax post request.
I want to know what all changes I need to make it on web method to accept JSON String.
public class Hello {
#POST
public String sayPlainTextHello() {
return "Hello Jersey";
}
}
Need to break down your requests. First, you want to accept a JSON string. So on your method you need
#Consumes(MediaType.APPLICATION_JSON)
Next, you need to decide what you want your method to obtain. You can obtain a JSON string, as you suggest, in which case your method would look like this:
#Consumes(MediaType.APPLICATION_JSON)
public String sayPlainTextHello(final String input) {
Or alternatively if your JSON string maps to a Java object you could take the object directly:
#Consumes(MediaType.APPLICATION_JSON)
public String sayPlainTextHello(final MyObject input) {
You state that you want to return a JSON string. So you need:
#Produces(MediaType.APPLICATION_JSON)
And then you need to actually return a JSON string:
return "{\"result\": \"Hello world\"}";
So your full method looks something like this:
#PATH("/hello")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String sayPlainTextHello(final String input) {
return "{\"result\": \"Hello world\"}";
}
Regarding using AJAX to send and receive, it would look something like this:
var myData="{\"name\": \"John\"}";
var request = $.ajax({
url: "/hello",
type: "post",
data: myData
});
request.done(function (response, textStatus, jqXHR){
console.log("Response from server: " + response);
});
This will work. "path" is the relative URL path to be used in AJAX call.
public class Hello {
#POST
#Path("/path")
#Produces({ "text/html" })
public String sayPlainTextHello() {
return "Hello Jersey";
}
}

Categories

Resources