I want to build a small RESTful Service, send a PUT request with an Object of a class I created (MyObject), and getting a response with only status.
My controler:
#RestController
public class MyControler {
#RequestMapping(path = "/blabla/{id}", method = RequestMethod.PUT)
#ResponseBody
public ResponseEntity<String> putMethod (#PathVariable("id") Long id,
#RequestBody MyObject t) {
/*todo*/
return new ResponseEntity<String>(HttpStatus.OK);
}
My Test App
#SpringBootApplication
public class App {
public String httpPut(String urlStr) {
MyObject myObject = new MyObject(p,p,....);
URI url = null;
HttpEntity<MyObject> requestEntity;
RestTemplate rest = new RestTemplate();
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
List<MediaType> list = new ArrayList<MediaType>();
list.add(MediaType.APPLICATION_JSON);
headers.setAccept(list);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Content-Type", "application/json");
requestEntity = new HttpEntity<Transaction>(t, headers);
ResponseEntity<String> response =
rest.exchange(url, HttpMethod.PUT, requestEntity, MyObject.class);
return response.getStatusCode().getValue();
}
Im getting an HttpClientErrorException: 400 Bad Request
Where is my mistake? What I want is for Spring to automaticly serialize the MyObject. MyObject class is implementing serializable.
What do I miss?
}
Maybe you're doing to much?
Did you try to put the object as json via postman or something similar? If so what is the response?
Nevertheless i created a minimal example for consuming a service via Springs RestTemplate.
This is all needed code for getting a custom object AND putting a custom object via RestTemplate
public void doTransfer(){
String url = "http://localhost:8090/greetings";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Greeting> greeting = restTemplate.getForEntity(url, Greeting.class);
LOGGER.info(greeting.getBody().getValue());
Greeting myGreeting = new Greeting();
myGreeting.setValue("Hey ho!");
HttpEntity<Greeting> entity = new HttpEntity<Greeting>(myGreeting);
restTemplate.exchange(url, HttpMethod.PUT, entity, Greeting.class);
}
I've provided a sample project with a sender (maybe not a good name .. it is the project with the greetings endpoint) and a receiver (the project which consumes the greetings endpoint) on Github
Try to do this:
ResponseEntity<MyObject> responseSerialized =
rest.exchange(url, HttpMethod.PUT, requestEntity, MyObject.class);
Related
I implement a client application. This application consume a Rest webservice and these service return and html page as a variable in a model.
I take these html page successfully from Rest Service and try to write to a blank html page.
My code to write html page.
public void writeToHtml(ResponseModel response) {
FileWriter fWriter = null;
BufferedWriter writer = null;
try {
fWriter = new FileWriter(src/main/resources/templates/test.html);
writer = new BufferedWriter(fWriter);
writer.write(response.getHtmlPage());
writer.newLine();
writer.close();
} catch (Exception e) {
}
}
These function can take htmlPage from ResponseModel and write successfully to test.html
Untill there everthing work properly and my controller display it on secreen.
However, if I again call same Rest service, it can again write to "test.html" but, on the screen it shows the first created html page.
Probably it cache the first html and if I rewrite again. I just take cache one.
My Controller
#RequestMapping(value = "/testPath", method = RequestMethod.POST)
public String payment(RequestModel paymentInfoModel, BindingResult bindingResult, Model model) {
RestTemplate restTemplate = new RestTemplate();
ResponseModel response = restTemplate.postForObject(url, request, ResponseModel.class);
writeToHtml(response);
return "test";
}
Could you help me to solve these issue ?
IDEA : Inteliji
I solved my problem a bit differently:
#RequestMapping(value = "/testPath", method = RequestMethod.POST, produces = "text/html")
#ResponseBody
public String payment(RequestModel paymentInfoModel, BindingResult bindingResult, Model model) {
RestTemplate restTemplate = new RestTemplate();
ResponseModel response = restTemplate.postForObject(url, request, ResponseModel.class);
writeToHtml(response);
return response.getHtmlPage();
}
So I don't need to create an HTML page.
I have created a rest webservice which has a below code in one method:
#POST
#Path("/validUser")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject validUserLogin(#QueryParam(value="userDetails") String userDetails){
JSONObject json = null;
try{
System.out.println("Service running from validUserLogin :"+userDetails);
json = new JSONObject(userDetails);
System.err.println("UserName : "+json.getString("userName")+" password : "+json.getString("password"));
json.put("httpStatus","OK");
return json;
}
catch(JSONException jsonException) {
return json;
}
}
I am using Apache API in the client code.And below client code is calling this service, by posting some user related data to this service:
public static String getUserAvailability(String userName){
JSONObject json=new JSONObject();
try{
HttpContext context = new BasicHttpContext();
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
URI uri=new URIBuilder(BASE_URI+PATH_VALID_USER).build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/json");
json.put("userName", userName);
StringEntity stringEntity = new StringEntity(json.toString());
request.setEntity(stringEntity);
HttpResponse response = client.execute(request,context);
System.err.println("content type : \n"+EntityUtils.toString(response.getEntity()));
}catch(Exception exception){
System.err.println("Client Exception: \n"+exception.getStackTrace());
}
return "OK";
}
The problem is, I am able to call the service, but the parameter I passed in the request to service results in null.
Am I posting the data in a wrong way in the request. Also I want to return some JSON data in the response, but I am not able to get this.
With the help of Zack , some how i was able to resolve the problem,
I used jackson-core jar and changed the service code as below.
#POST
#Path("/validUser")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject validUserLogin(String userDetails){
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(userDetails, JsonNode.class);
System.out.println("Service running from validUserLogin :"+userDetails);
System.out.println(node.get("userName").getTextValue());
//node.("httpStatus","OK");
return Response.ok(true).build();
}
I have to send JSON data from one service method to the other using postForObject() method.
I saw one example on RestTemplate on this link.
postForObject() method has the following format:
User returns = rt.postForObject(uri, u, User.class, vars);
Or
User returns = rt.postForObject(uri, u, User.class);
I want to know that, after using postForObject() method, if we implement the service method to accept the User object, how it will look like?
In my project, I have code like
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
String uri = "http://testcode.com/myapp/api/launchservices";
ServiceRequest request = new ServiceRequest();
request.setId(UUID.randomUUID().toString());
....
I am getting error at this line:
ServiceRequest req = restTemplate.postForObject(uri, request, ServiceRequest.class);
while executing this, I am getting this error mesage:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:537)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:493)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:302)
my implementation method is:
#RequestMapping(value = "/launchservices", method = RequestMethod.POST)
#ResponseBody
public boolean launchServices(#PathVariable ServiceRequest request) {
System.out.println("Request: "+request.toString());
return true;
}
How to get rid of this? What will be the URI?
I got solution to this problem.
In this example,method postForObject returns an object of class "ServiceRequest"
ServiceRequest req = restTemplate.postForObject(uri, request, ServiceRequest.class);
So, the method that implements this service with the above 'uri' should return an object of class ServiceRequest
All it needs is, slight modification in implementation method as below
#RequestMapping(value = "/launchservices", method = RequestMethod.POST, headers = "Accept=application/json")
#ResponseBody
public ServiceRequest launchServices(#RequestBody ServiceRequest request) {
System.out.println("Request: "+request.toString());
return request;
}
Hello In frist time I want apologize if my english isn't so good
I want send Multipart request to the server by Apache HttpClient. This request consist from several types of parts. One of these part is JSON. JSON is created by Jackson.
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xx:8080/synchronize");
HttpResponse response =null;
CProject project = new CProject();
project.setId(10L);
project.setName("name");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(project);
MultipartEntity multipart = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE);
multipart.addPart("project", new StringBody(json,"application/json",Charset.forName("UTF-8")) );
httppost.setEntity(multipart);
response = httpclient.execute(httppost);
Structure of CProject is very simple
public class CProject implements Serializable{
private Integer id;
private String name;
}
And I wand catch this request on server as parameter with anotations #RequestParam or #ModelAttribute but no with #RequestBody because this catch full request - and I need send multiply parameters(Multipart Entity).
Code on server
#RequestMapping (value = "/synchronize", method = RequestMethod.POST)
public #ResponseBody
List<Object> getRequest (#RequestParam CProject project, HttpServletResponse response)
{
return null;
}
Problem is that variable project is created but its atributes are null.
I try several tutorials on net what works with #RequestBody and send request on server and set full header as "application/json". And my application works if I change header of full request as JSON and send them on server, and catch this as #RequestBody on server this work. But I need send json as parameter.
Thanks for any ideas.
i want to create a spring mvc rest call and the response should be the results from the mongo db (Basic)DBObject. the DBObject is, as far as i know, a JSON object. is it possible to return this objects or should i return the normal string content of them?
this is the solution i have so far:
#RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET)
public ResponseEntity<String> getContentByIdsAsJSON(#PathVariable("ids") String ids)
{
String content = null;
StringBuilder builder = new StringBuilder();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "text/html; charset=utf-8");
List<String> list = this.contentService.findContentByListingIdAsJSON(ids);
if (list.isEmpty())
{
content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><error>no data found</error>";
return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
}
for (String json : list)
{
builder.append(json + "\n");
}
content = builder.toString();
return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
}
does anyone have a better solution for that requirement?
thx very much in advance.
simon
I'm see a strange thing in you code. Do you must return json or xml? If you must return json it's simple in your situation, #ResponseBody do the magic
#RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET)
#ResponseBody
public MyGreatContentObject getContentByIdsAsJSON(#PathVariable("ids") String ids) {
return this.contentService.findContentByListingId(ids);
}
in any way, i'm think you still must learn base concepts a little more