GWT- POST object/json and go to another page - java

I referred this link : How to post data and redirect to another page using GWT?
I can use formpanel but I am stuck somewhere ,please help .
This is my code :
HashMap<String, String> map = new HashMap<String, String>();
map.add(...some information....); //want to send this map in POST
I want to send the map using POST and also I want to go to another page.
I can use this code (answered in How to post data and redirect to another page using GWT?):
FormPanel form = new FormPanel("_self");
form.setMethod(FormPanel.METHOD_GET);
Hidden params0 = new Hidden("param1", "value1");
Hidden params1 = new Hidden("param1", "value2");
Hidden params2 = new Hidden("param2", "value3");
FlowPanel panel = new FlowPanel();
panel.add(params0);
panel.add(params1);
panel.add(params2);
form.add(panel);
form.setAction(GWT.getModuleBaseURL() + "../test");
RootPanel.get().add(form);
form.submit();
But how do I send already created map along with POST ?
At server side :
#RequestMapping(value = "/test",method = RequestMethod.POST)
#ResponseBody
public String test(#RequestBody final HashMap<String, String> map,HttpSession session)
{
//use the map
return another-page.jsp
}

Probably better to send data via RPC or AJAX and redirect to another page by Location.assign() or Location.replace(). If you expect the server to provide dynamic URL to redirect you can send it as a response for the RPC or AJAX request. In current example AJAX request is used:
// map is your existing map object
JSONObject data = new JSONObject();
for (String key : map.keySet()) {
data.put(key, new JSONString(map.get(key)));
}
RequestBuilder request = new RequestBuilder(RequestBuilder.GET, "<URL>");
request.setRequestData(data.toString());
request.setCallback(new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
String url = response.getText();
// url to redirect
Window.Location.assign(url);
}
#Override
public void onError(Request request, Throwable exception) {
// handle error
}
});
request.send();
Or you can serialize map to String and pass it as hidden field of a POST request.
Client code:
String buffer = Streamer.get().toString(map);
FlowPanel panel = new FlowPanel();
panel.add(new Hidden("map", buffer));
FormPanel form = new FormPanel("_self");
form.setMethod(FormPanel.METHOD_POST);
form.setAction(<URL>);
form.add(panel);
RootPanel.get().add(form);
form.submit();
Server code:
#RequestMapping(value = <URL>,method = RequestMethod.POST)
#ResponseBody
public String test(#RequestBody String mapString,HttpSession session)
{
Map<String, String> map = (Map<String, String>) Streamer.get().fromString(mapString);
// use the map
return another-page.jsp
}

Related

RestTemplate POST with query parameter without request body

I am trying a POST method with RestTemplate. I need my request to have only 1 query parameter, without body (e.g. localhost:8080/predictions/init?date=xxxx).
My current code is the following :
String url = "http://localhost:8080/predictions/init";
String dateToGenerate = "xxxx";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
Map map = new HashMap<String, String>();
map.put("Content-Type", "application/json");
headers.setAll(map);
Map req_payload = new HashMap();
req_payload.put("date", dateToGenerate);
HttpEntity<?> request = new HttpEntity<>(req_payload, headers);
restTemplateApi.postForEntity(url, request, String.class);
The side of the REST controller I'm trying to call is the following :
#PostMapping
#ResponseStatus(HttpStatus.OK)
public PredictionGenerated initializeOnePrediction(#RequestParam #NotEmpty String date) {
.............................
.............................
}
I'm currently receiving org.springframework.web.client.HttpClientErrorException: 400 null.
Any ideas?
If you have any many query param then set all in Multiple value Map as below.
MultiValueMap<String, String> param= new
LinkedMultiValueMap<String, String>();
param.put("date", datevalue);
Then create Http header add required content.
HttpHeaders headers = new HttpHeaders()
header.setContentType("application/json");
Create the URL as below.
URI url = UriComponentsBuilder.fromHttpUrl(base url)
.queryParams(param)
.build();
HttpEntity<?> request = new HttpEntity<>(req_payload,
headers);
restTemplateApi.postForEntity(url, request, String.class);

I cannot send an HTTP request (500 internal server error)

I am currently receiving the following error for the http request am sending. I am trying to send a JSON Array list to trigger a method in the receiving end so as it saves the list in its database.
The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the website's server, but the server could not be more specific on what the exact problem is.
Websites phrase 500 errors in many ways but they're all basically saying the same thing: there's a general server issue going on right now.
Most of the time there isn't anything you can do but contact the website directly and then wait on them to fix it.
In the off chance there is a problem on your end, try clearing the cache and deleting any cookies from the site with the error.
Please find the error below:
org.springframework.web.client.HttpServerErrorException: 500 Internal Server
public static String FRONT_URL;
public static String BACK_URL;
public static final String REST_SYNC = "rest/sync";
public static final String REST_API = "rest/api";
private Logger log = Logger.getLogger(FrontSynchronizer.class);
static final Logger synclog = Logger.getLogger("sync");
ResourceBundle rb = ResourceBundle.getBundle("bundles.sync-application-resources", Locale.getDefault());
//method sending the request
public void syncApplications(List<SchemeApplication> accList) {
schemeApplicationDto=new SchemeApplicationDto();
FRONT_URL = rb.getString("sync.front.url").concat(REST_SYNC);
BACK_URL = rb.getString("sync.back.url").concat(REST_API);
JSONArray array = new JSONArray();
if (accList != null && accList.size() > 0) {
for (SchemeApplication student : accList) {
schemeApplicationDto.setId(student.getId());
schemeApplicationDto.setAccountID(student.getAccountID());
schemeApplicationDto.setNoOfPersonsEmployedLocal(student.getNoOfPersonsEmployedLocal());
schemeApplicationDto.setLocalmainclients(student.getLocalmainclients());
JSONObject studentJSON = new JSONObject(schemeApplicationDto);
array.put(studentJSON);
}
}
HttpHeaders headers = new HttpHeaders();
JSONObject object = new JSONObject();
object.put("array", array);
headers.setContentType(MediaType.APPLICATION_JSON);
RestTemplate restTemplate = this.createnewTemplate();
String url = BACK_URL.concat("/application");
HttpEntity<String> requestEntity = new HttpEntity<String>(object.toString(), headers);
ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity,
Boolean.class);
if (responseEntity.getBody())
{
for(SchemeApplication scheme:accList) {
schemeApplicationService.getDao().delete(scheme);
}
}
}
public RestTemplate createnewTemplate() {
// RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectTimeout(120000);
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
return restTemplate;
}
// method that needs to process the request
//The method is trying to send an Array list so as the receiving end can receive the list and save it in its database.
#RequestMapping(value = "application", method = RequestMethod.POST)
public Boolean getAllArchivedpplications(#RequestBody String schemeJson) {
List<SchemeApplication> accList = null;
try {
accList = new ArrayList<SchemeApplication>();
if (StringUtils.isNotEmpty(schemeJson)) {
JSONObject listObject = new JSONObject(schemeJson);
JSONArray entryArray = listObject.getJSONArray("array");
for (int i = 0; i < entryArray.length(); i++) {
JSONObject res = new JSONObject(entryArray.get(i).toString());
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
schemeApplication doc = mapper.readValue(res.toString(),
new TypeReference<schemeApplication>() {
});
accList.add(doc);
}
schemeService.getDao().save(accList); // Service.save accountlist;
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
#RequestBody must work on an object.
Standard way to do this kind of work in two ways:
Form a class having class files with same name and structure with your json data you are sending and capture that data in by #RequestBody annotation
As you are sending data as String, send it as request param, and use #RequestParam instead of #RequestBody and parse the way you need to do things. For I think for this kind of arrayList of bulk data you are working with, option 1 will be better/feasible.
For details you can check here: #RequestBody and #ResponseBody annotations in Spring

How can I pass headers using RestTemplate?

In my method I initially used RestTemplate postForObject method to post request to an endpoint. Now I have to add default OAuth token and pass it as Post request. Is there any way I can pass both request as well as Default Header as part of POST request by using postForObject?
Initiall I used below postForObject
String result = restTemplate.postForObject(url, request, String.class);
I am looking for something like below
restTemplate.exchange(url,HttpMethod.POST,getEntity(),String.class );
Here is my code
private final String url;
private final MarkBuild header;
public DataImpl(#Qualifier(OAuth) MarkBuild header,RestTemplate restTemplate) {
this.restTemplate= restTemplate;
this.header = header;
}
public void postJson(Set<String> results){
try {
Map<String, String> requestBody = new HashMap<>();
requestBody.put("news", "data");
JSONObject jsonObject = new JSONObject(requestBody);
HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), null);
String result = restTemplate.postForObject(url, request, String.class);
}
}
Below is getHttpEntity which I want to pass with Post request
private HttpEntity getHttpEntity(Set <String>results) {
return new HttpEntity<>( null, getHttpHeaders() );
}
private HttpHeaders getHttpHeaders() {
return header.build();
}
}
Is there any way I can pass both request as well as Default Header as
part of POST request by using postForObject?
Yes, there is a way to do that, I can give a basic example:
HttpHeaders lHttpHeaders = new HttpHeaders();
lHttpHeaders.setContentType( MediaType.APPLICATION_JSON );//or whatever it's in your case
String payload="<PAYLOAD HERE>"
try
{
String lResponseJson = mRestTemplate.postForObject( url, new HttpEntity<Object>( payload, lHttpHeaders ), String.class);
return lResponseJson;
}
catch( Exception lExcp )
{
logger.error( lExcp.getMessage(), lExcp );
}
Let me know if this doesn't work!!

Forward a request with the exact same json body

I have a SpringBoot application which simply acts as a middleman. It receives an API request in JSON and forwards this to another server S by calling S's API with the exact same body.
I was exploring the solutions and came across a solution which involved the usage of RestTemplate and MultiValueMap. However, since the json body contains objects rather than simple String, I believe I have to create a DTO with corresponding POJO for the solution to work.
May I ask is the above the only solution, or there is a simple way to forward the request over and get back the response?
Even complex and nested JSON objects can be taken into a Map with key as String and value as Object.
I believe you should just use such a map as your request body and transfer the same to another api.
The middleman server can expose a endpoint that accepts a #RequestBody of Object and
HttpServletRequest then use RestTemplate to forward it to the remote server.
The middleman
#RestController
#RequestMapping("/middleman")
public class MiddleManRestController {
private RestTemplate restTemplate;
#PostConstruct
public void init() {
this.restTemplate = new RestTemplate();
this.restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(this.restTemplate.getRequestFactory()));
}
#RequestMapping(value = "/forward", method = RequestMethod.POST)
public ResponseEntity<Object> forward(#RequestBody Object object, HttpServletRequest request) throws RestClientException {
//setup the url and path
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("Remote server URL").path("EnpointPath");
//add query params from previous request
addQueryParams(request, builder);
//specify the method
final RequestEntity.BodyBuilder requestBuilder = RequestEntity.method(HttpMethod.POST, builder.build().toUri());
//add headers from previous request
addHeaders(request, requestBuilder);
RequestEntity<Object> requestEntity = requestBuilder.body(object);
ParameterizedTypeReference<Object> returnType = new ParameterizedTypeReference<Object>() {};
//forward to the remote server
return this.restTemplate.exchange(requestEntity, returnType);
}
private void addHeaders(HttpServletRequest request, RequestEntity.BodyBuilder requestBuilder) {
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
requestBuilder.header(headerName, headerValue);
}
}
private void addQueryParams(HttpServletRequest request, UriComponentsBuilder builder) {
final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
Map<String, String[]> parameterMap = request.getParameterMap();
if (parameterMap != null) {
parameterMap.forEach((key, value) -> queryParams.addAll(key, Arrays.asList(value)));
}
builder.queryParams(queryParams);
}
}

How do I add params and Cookie to http post java request?

I am trying to invoke a webservice method which takes 2 input parameters and also needs a cookie to authenticate.
PostMethod method = new PostMethod("webservice EP URL");
NameValuePair code = new NameValuePair("Code", "");
NameValuePair revision = new NameValuePair("Rev", "Latest");
NameValuePair targetUri = new NameValuePair("TARGET", "GetObject");
method.setRequestBody(new NameValuePair[] { code, revision,targetUri});
int statusNew = client.executeMethod(method);
I dont know how to achieve it. Above code is what i am doing currently.
Most probably you are dealing with RESTful web services (Just my guess as you are passing parameters as http form params). Here is how to pass cookies
method.setRequestHeader("Cookie", "special-cookie=value");
Here just change "special-cookie=value" to your specific cookie that you are trying to pass.
EDIT: Adding cookie to SOAP request:
The quickest way to do is as follows
(Assuming that the call object you are using is an instance of org.apache.axis.client.Call)
call.setProperty(
org.apache.axis.client.Call.SESSION_MAINTAIN_PROPERTY,
new Boolean(true));
call.setProperty(
org.apache.axis.transport.http.HTTPConstants.HEADER_COOKIE2,
"\r\nCookieName=" + "CookieValue");
Please check "Use a SOAPAction HTTP Header" topic on this link.
Using the SOAP Handler, we can pass the headers in the request and it will do the job.
GetObject_Service_Impl impl = new GetObject_Service_Impl();
// Get Iterator for all service ports
Iterator iter = impl.getPorts();
// Now create a new List of HandlerInfo objects - only one really.
// Our client handler
List handlerChain = new ArrayList();
handlerChain.add(new HandlerInfo(SoapHandler.class, null, null));
// Get Handler Registry
HandlerRegistry registry = impl.getHandlerRegistry();
// Register each port with the handler
while (iter.hasNext())
registry.setHandlerChain((QName) iter.next(), handlerChain);
And Write a new class say SoapHandler.java as below
public class SoapHandler extends GenericHandler {
HandlerInfo hi;
public void init(HandlerInfo info) {
hi = info;
}
public QName[] getHeaders() {
return hi.getHeaders();
}
public boolean handleResponse(MessageContext context) {
return true;
}
/**
* This method is use to add custom headers to existing SAOP request
*/
public boolean handleRequest(MessageContext context) {
System.out.println("response");
try {
SOAPMessageContext smc = (SOAPMessageContext) context;
SOAPMessage message = smc.getMessage();
MimeHeaders hd = message.getMimeHeaders();
hd.addHeader("Authorization", "Basic some credentials");
} catch (Exception e) {
throw new JAXRPCException(e);
}
return true;
}
}
And thats it.....its ready to go.

Categories