Just see the code snippet of SpringMVC-3.2.x controller action method. Its quite easy to generate JSON but unable to add addtional custom header only for this action/specific action method for specific controller. not common for all JSON #ResponseBody action method .
#RequestMapping(value="ajaxDenied", method = RequestMethod.GET)
public #ResponseBody Map<String, Object> ajaxDenied(ModelMap model) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("severity", "error");
message.put("summary", "Restricted access only");
message.put("code", 200);
Map<String, Object> json = new HashMap<String, Object>();
json.put("success", false);
json.put("message", message);
return json;
}
In the different way I could add additional headers as my demand but here is some problem in generating pure JSON. Its generate buggy JSON and able to parse few browser.
#RequestMapping(value="ajaxSuccess", method = RequestMethod.GET)
public ResponseEntity<String> ajaxSuccess(){
Map<String, Object> message = new HashMap<String, Object>();
message.put("severity", "info");
message.put("location", "/");
message.put("summary", "Authenticated successfully.");
message.put("code", 200);
Map<String, Object> json = new HashMap<String, Object>();
json.put("success", true);
json.put("message", message);
String data = "";
try {
ObjectMapper mapper = new ObjectMapper();
data = mapper.writeValueAsString(json);
} catch (Exception e) { //TODO
}
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=UTF-8");
headers.add("X-Fsl-Location", "/");
headers.add("X-Fsl-Response-Code", "302");
return (new ResponseEntity<String>(data, headers, HttpStatus.OK));
}
this action method could generate JSON String with escape character rather than pure JSON so depend on browser how it will be parse, Its cause failure for chrome. The output just look like
"{\"message\":{\"summary\":\"Authenticated successfully.\",\"location\":\"/\",\"severity\":\"info\",\"code\":\"200\"},\"success\":true}"
but our desired output
{
"message":{
"summary": "Authenticated successfully.",
"location":"/",
"severity":"info",
"code":"200"
},
"success":true
}
I want to generate pure JSON with additional headers based on conditions for specific action of specific controller.
You can add headers to the ResponseEntity builder. I think it is cleaner this way.
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
// ...
#GetMapping("/my/endpoint")
public ResponseEntity myEndpointMethod() {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8");
return ResponseEntity.ok()
.headers(headers)
.body(data);
}
Here is the solution as the suggestion of M. Deinum
#RequestMapping(value="ajaxSuccess", method = RequestMethod.GET)
public ResponseEntity<Map<String, Object>> ajaxSuccess(){
Map<String, Object> message = new HashMap<String, Object>();
message.put("severity", "info");
message.put("location", "/");
message.put("summary", "Authenticated successfully.");
message.put("code", 200);
Map<String, Object> json = new HashMap<String, Object>();
json.put("success", true);
json.put("message", message);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=UTF-8");
headers.add("X-Fsl-Location", "/");
headers.add("X-Fsl-Response-Code", "302");
return (new ResponseEntity<Map<String, Object>>(json, headers, HttpStatus.OK));
}
You can also use HttpServletResponse for adding your status and headers in a more easy way:
#RequestMapping(value="ajaxSuccess", method = RequestMethod.GET)
#ResponseBody
public String ajaxSuccess(HttpServletResponse response) {
response.addHeader("header-name", "value");
response.setStatus(200);
return "Body";
}
Therefore you need to add following maven dependency as provided:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.53</version>
<scope>provided</scope>
</dependency>
Related
I have a RestController and when I call the method:
#RequestMapping(value = "/sigla/{sigla}")
#ResponseBody
public PaisDTO obterPorSigla(#PathVariable String sigla) {
return service.obterPorSigla(sigla);
}
If a record is found, I get a good JSON response:
{"nome":"Brasil","sigla":"BR","quantidadeEstados":27}
but when nothing is found on database the RestController returns null and I get a empty response, completely blank body.
How can I display a empty JSON instead of a blank response? Like bellow:
{}
Complete Controller:
#RestController
#RequestMapping("/pais")
public class PaisController {
#Autowired
private PaisService service;
#RequestMapping
public ResponseEntity<List<PaisDTO>> obterTodos() {
return CreateResponseEntity.getResponseEntity(service.obterTodos());
}
#RequestMapping(value = "/sigla/{sigla}", method = RequestMethod.GET, consumes="application/json", produces="application/json")
public ResponseEntity<PaisDTO> obterPorSigla(#PathVariable String sigla) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
PaisDTO paisDTO = service.obterPorSigla(sigla);
if(paisDTO != null) return new ResponseEntity<PaisDTO>(paisDTO, headers, HttpStatus.OK);
else return new ResponseEntity<PaisDTO>(headers, HttpStatus.OK);
}
Solution 1:
You have to implement you entity class with Serializable
Solution 2:
Your class should have getter and setter
In my case the getter and setter were given protected access modifiers. so I changed them to public and vola it worked
First, if you're using #RestController annotation you don't need the #ResponseBody annotation, get rid of that.
Second if you're trying to have REST Controller, then you're missing a few things, do it like this:
#RequestMapping(value = "/sigla/{sigla}", method = RequestMethod.GET, consumes = "application/json", produces="application/json")
public ResponseEntity<PaisDTO> obterPorSigla(#PathVariable String sigla) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
PaisDTO paisDTO = service.obterPorSigla(sigla);
if(paisDTO != null) return new ResponseEntity<>(paisDTO, headers, HttpStatus.OK);
else return new ResponseEntity<>(headers, HttpStatus.OK);
}
In the example above if you'll get null then you'll return an empty response JSON.
The only way that I could find was to create an empty class
#JsonSerialize
public class EmptyJsonBody {
}
Then add this to your response
#PostMapping(value = "/sigla/{sigla}")
public ResponseEntity obterPorSigla(#PathVariable String sigla) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
PaisDTO paisDTO = service.obterPorSigla(sigla);
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.ok().headers(headers);
if(paisDTO != null) {
return responseBuilder.body(paisDTO);
} else {
return responseBuilder.body(new EmptyJsonBody());
}
}
In a Spring Boot controller, I am receiving json and want to "forward" it without any processing:
#RequestMapping(value = "/forward", method = RequestMethod.POST)
public void abc(#RequestBody GeneralJsonRepresentation json, HttpServletRequest request) {
restTemplate.postForEntity(endpoint, json, Object.class)
}
Is it possible to accomplish this, for instance with an implementation of GeneralJsonRepresentation, assuming the controller has no knowledge of the json format and that the received content type is application/json?
You may not even need the GeneralJsonRepresentation if you just use a String.
I created a small working snippet:
#RequestMapping(path="/forward", method = RequestMethod.POST)
public ResponseEntity<String> forward(#RequestBody String postData) {
// maybe needed configuration
final RestTemplate restTemplate = new RestTemplateBuilder().basicAuthorization("user", "password").build();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(postData, headers);
final String targetUrl = "http://targethost/endpoint";
final ResponseEntity<String> response = restTemplate.postForEntity(targetUrl, entity, String.class);
return ResponseEntity.created(...).build();
}
I have a method, which changes the status from 'Active' to 'InActive' and vice
versa, of a record, by fetching it's id.
Now, I want to convert it to return a ResponseEntity object, inside which, I have a map stored
When I test my method, I get a 400: Bad Request
////////////////////////Old Method////////////////
#RequestMapping("toggleStatus")
public #ResponseBody void toggleStatus(#RequestParam("resourceId") Long resourceId ){
ResourceElementMaster resourceElementMaster = resourceElementService.findById(resourceId);
if(resourceElementMaster.getIsActive() == true) {
resourceElementMaster.setIsActive(false);
} else {
resourceElementMaster.setIsActive(true);
}
resourceElementService.update(resourceElementMaster);
}
//////////////////////New Method/////////////////////////////
#RequestMapping(value="toggleStatus",method=RequestMethod.PUT)
public #ResponseBody ResponseEntity<Map<String, Object>> toggleStatus(#RequestBody Long resourceId ){
Map<String, Object> mapToggle=new HashMap<String, Object>();
ResourceElementMaster resourceElementMaster = resourceElementService.findById(resourceId);
if(resourceElementMaster.getIsActive() == true) {
resourceElementMaster.setIsActive(false);
} else {
resourceElementMaster.setIsActive(true);
}
mapToggle.put("Update",resourceElementService.update(resourceElementMaster));
return new ResponseEntity<Map<String, Object>>(mapToggle, HttpStatus.OK) ;
}
How do I solve this??
You problem is, you are trying to pass an json to your /toggleStatus Method. But your #Controller accepts only a resourceIdof type Long.
So your response via Postman should be something like this:
PUT http://localhost:8080/toggleStatus?resouceId=42
also, there is no need for RequestEntity in your case. Modify your #controller like this:
#ResponseBody
#RequestMapping(value = "toggleStatus", method = RequestMethod.PUT)
public Object toggleStatus(#RequestParam Long resourceId ){
Map<String, Object> mapToggle = new HashMap<String, Object>();
ResourceElementMaster resourceElementMaster = resourceElementService.findById(resourceId);
resourceElementMaster.setIsActive(!resourceElementMaster.getIsActive());
mapToggle.put("Update", resourceElementService.update(resourceElementMaster));
return mapToggle;
}
Don't pass a json, you only need to pass the resourceId, which you are accepting as a parameter in your method toggleStatus.
Also, use #RequestParam, instead of #RequestBody :
#RequestMapping(value="toggleStatus",method=RequestMethod.POST)
public #ResponseBody ResponseEntity<Map<String, Object>> toggleStatus(#RequestParam(value = "resourceId") Long resourceId ){
Map<String, Object> mapToggle=new HashMap<String, Object>();
ResourceElementMaster resourceElementMaster = resourceElementService.findById(resourceId);
if(resourceElementMaster.getIsActive() == true) {
resourceElementMaster.setIsActive(false);
} else {
resourceElementMaster.setIsActive(true);
}
mapToggle.put("Update",resourceElementService.update(resourceElementMaster));
return new ResponseEntity<Map<String, Object>>(mapToggle, HttpStatus.OK) ;
}
I am trying to pass a parameter which is the userID and then get the response in the form of the JSON.
So if userID=1 then the response would be
[{"carname":"Honda","carmodel":"Civic"}]
and if userID=5then the response would be
[{"carname":"Honda","carmodel":"Civic"},{"carname":"VW","carmodel":"Golf"},{"carname":"Ford","carmodel":"Focus"}]
But for some reason, the parameters are not being passed and if they are then I am unable to retrieve values in JSON
This is my code below:
public void getComments(int userID){
String passURL = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(passURL, new Response.Listener<JSONArray>(){
#Override
public void onResponse(JSONArray jsonArray) {
try {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String carName = jsonObject.getString("carname");
String carModel = jsonObject.getString("carmodel");
UserStore userStore = new UserStore(carName, carModel);
list.add(userStore);
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("userID", Integer.toString(userID));
return params;
}
};
requestQueue.add(jsonArrayRequest);
}
I suspect it something to do with the fact that I am trying to get the response from the array after passing a parameter. My php works in Postman
Using mcxiaoke library version 1.0.14 and above
JsonArrayRequest
You need to set the Method as Post in JsonArrayRequest as like below
JsonArrayRequest jsonArrReq = new JsonArrayRequest(Method.POST,
url, null,new Response.Listener<JSONArray>()
{
......
//onResponse
......
}
getParams()
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("user", "Android");
return params;
}
I have a previous code for connecting to a webservice using httpclient. String entity it is working with no problem. I want to update it using volley. I tried the below code but it gives me unexpected, BasicNetwork.performRequest: Unexpected response code 400.
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject("{\"LoginDate\":\"\\/Date(" + today.getTime() + "+0800)\\/\",\"MAC\":\"00-00-00-12-12-12\",\"MerchantID\":\"xxxxx\",\"StationName\":\"WKSTN01\",\"UserName\":\"exampleuser\"}");
}catch (Exception e) {
e.printStackTrace();
}
Log.e("JSONOBEJCT", jsonObject.toString());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, URL, jsonObject , new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
Log.e("Response", jsonObject.toString());
pDialog.hide();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Error: " + error.getMessage());
pDialog.hide();
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("Authorization", messageHasValue);
return headers;
}
};
This is my old code and I just want to update it with volley, is there any way I can do it?...
StringEntity entity = new StringEntity(object.toString());
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URL);
entity.setContentType("application/json");
httpPost.addHeader("Authorization", messageHasValue);
httpPost.setEntity(entity);
Log.e("HTTPPOST ", httpPost.toString());
HttpResponse response = client.execute(httpPost);
HttpEntity resEntity = response.getEntity();
Its working now, I tried to upgrade my PHP version from 4 to 5 and format the TimeStamp.