web service in spring getParameter - java

I am creating a web service, but I am not getting the value I expect by using req.getParameter("key"). Can you please tell why I am getting values as null ?
Here, instead of getting "abcd" as value, I am getting null.
The request which I am hitting is:
http://localhost:8080/api.htm.
Post fields are:
username:abcd
#ResponseBody
#RequestMapping(value = {"api"}, method = {RequestMethod.POST})
public String apiSignUp(HttpServletRequest req) throws JSONException {
JSONObject json = new JSONObject();
Users user;
try {
String username = req.getParameter("username");

Related

How to set a variable endpoint to my URL for HTTP GET method?

I would like to make the endpoint of the URL in that method a variable one:
public User fetchUser() throws IOException {
URL url = new URL("https://api.github.com/users/octocat");
InputStreamReader reader = new InputStreamReader(url.openStream());
User user = new Gson().fromJson(reader, User.class);
if (user == null) {
logger.error("Could not return desired output.");
return null;
} else {
logger.info("The output returned.");
return user;
}
}
Modifying it to this does not solve the case (changed 'octocat' into '{endPoint}'):
public User fetchUser(#PathVariable String endPoint) throws IOException {
URL url = new URL("https://api.github.com/users/{endPoint}");
This is the GET method from my RestController:
#GetMapping("/user/info/{login}")
public User getUser(#PathVariable String login) throws IOException {
return userService.fetchUser();
}
The browser returns this message:
There was an unexpected error (type=Internal Server Error, status=500).
https://api.github.com/users/{endPoint}
Also, if I modify my URL to this:
URL url = new URL("https://api.github.com/users");
Then the response is this:
There was an unexpected error (type=Internal Server Error, status=500).
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
Help, please.
For your first exception, you could try using string concatenation to append the endpoint to the URL and see if the connection opens that way:
URL url = new URL("https://api.github.com/users/" + endpoint);
For your second exception, it looks like you're telling GSON you have an object of type User when you actually have an array of some sort. You may have to change the Type parameter in fromJson() so that gson can deserialize the json properly. Here is an example of deserializing arrays in gson.
Since I see you're using spring-web and this looks like a RESTful API, I would also suggest configuring a RestTemplate Bean and injecting it into your service to make the request out to github rather than using java.net.url. You can find a nice guide on spring.io for how that works.

Consume Post method Rest + SpringBoot

I have been searching all morning and i think i'm missing something .
i have a Spring boot controller with a method to save a client.
this is the method :
// ajouter un client
#RequestMapping(value="/AjoutClient/{clientData}", method=RequestMethod.POST)
public String AjoutClient(#PathVariable String clientData) {
Client c = new Client();
c.setNomClient(clientData.split(";")[0]);
c.setPrenomClient(clientData.split(";")[1]);
c.setAdresseClient(clientData.split(";")[2]);
c.setTelClient(clientData.split(";")[3]);
c.setEmailClient(clientData.split(";")[4]);
c.setCinClient(clientData.split(";")[5]);
client.save(c);
return "test";
}
i want to consume this method from another application with this method :
#RequestMapping(value="/ajoutClient", method=RequestMethod.POST)
public void ajout(#RequestParam("nom") String nom,#RequestParam("prenom") String prenom,#RequestParam("adr") String adr,#RequestParam("tel") String tel,#RequestParam("mail") String mail,#RequestParam("cin") String cin) {
String ClientData=nom+";"+prenom+";"+adr+";"+tel+";"+mail+";"+cin;
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> request = new HttpEntity<>(new String(ClientData));
ResponseEntity<String> response = restTemplate
.exchange("http://localhost:9093/AjoutClient/"+ClientData, HttpMethod.POST, request, String.class);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
}
** explication : i get the values from a form and construct a string with those values, then try to send that string to my clientController.
PS: i can't send client object, i have to send the values one by one then create the client object in the clientController.
i'm feeling pretty lost because i can see that something is wrong but i don't know what is it.
First of all I would suggest you avoid using #PathVariable for passing the data like this.
You're already sending everything in the request body, so first step is to change:
public String AjoutClient(#PathVariable String clientData) {
to
public String AjoutClient(#RequestBody String clientData) {
and
restTemplate.exchange("http://localhost:9093/AjoutClient/" + ClientData, HttpMethod.POST, request, String.class);
to just
restTemplate.exchange("http://localhost:9093/AjoutClient", HttpMethod.POST, request, String.class);
Then if you're expecting 201 status then you have to return it:
public ResponseEntity<String> AjoutClient(#RequestBody String clientData) {
...
return ResponseEntity.created(null).body("test");
}
PS: Please pay attention to what #JB Nizet mentioned, cause he has a point here. Just research that keywords (google them) or read some tutorials e.g https://www.baeldung.com/java-url-encoding-decoding or https://www.baeldung.com/rest-template and you'll easily find out more about standard practices.

JSON Object as #RequestBody on Spring 4.16

So i have this android application that send jsonObject for a jsonObjectRequest (I'm using volley) with POST method. The JSON file was sent but the server (this is where i'm using Spring btw) is not responding. The code pretty much like these.
Android Code:
JSONObject jsonObject = new JSONObject(data);
final JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
userToken = response.getString(TAG_TOKEN);
// blablabla
Server Code:
#RestController
#RequestMapping("/auth/")
public class AuthController {
String userEmail;
String userPassword;
#RequestMapping(value = "/login", method = RequestMethod.POST)
public LoginResponse loginResponse(#RequestBody Auth auth){
userEmail = auth.getEmail();
userPassword = auth.getPassword();
// blablabla
Auth Object:
public class Auth {
private String email;
private String password;
// blablabla
It seems like the server didn't receive the JsonObject from the android client correctly. (The server is able to send JSON to android client perfectly in another case, though). I'm using spring-4.16, jackson-core, jackson-annotation, jackson-databind (2.2.2). Thanks in advance!
From the code you supplied first thing that I suspect can be is that JSONObject doesn't have same field's name with Auth on server.
Also it is possible that HttpMessageConverter which is used for mapping objects from request to object in controller is not doing his job correctly.
I would first try to just try to recieve parameters from body, without Auth object. If Spring maps it fine than HttpMessageConverter is the problem, if it does not than the usage of #RequestBody, which I can't be from code you supplied.

RestFul service issue

Trying to setup a restful service component that update a database table. Tried using both Spring RestTemplate as well as apache commons restful impl and both seems to no work.
On using
Option 1: Using Spring RestTemplate : Results in following error
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token
Option 2: Using using org.apache.commons.httpclient.methods.PostMethod; results in following errors
Server side error:
org.codehaus.jackson.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
Client side error:
The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().
My Restful service method is annotated as "Post" and consumes "JSON". My client side controller which initiates the RestFul call, code below
#RequestMapping(value="/update", consumes="application/json")
public void updateMaintReport(
#RequestBody Map<String, String> formModelData,
HttpServletRequest request,
HttpServletResponse response)
throws IOException,JsonMappingException {
logger.log(LogLevel.DEBUG, "REACHED method updateMaintReport..");
System.out.println("Reached method updateMaintReport.....");
boolean errorEncountered = false;
ReportingSession repSession = null;
HttpSession session = request.getSession(false);
if(session==null) {
// TODO: code for handling invalid/expired session
} else {
repSession = (ReportingSession)session.getAttribute(ReportingWebConstants.REPORTING_SESSION);
if(repSession==null) {
errorEncountered = true;
}
}
if(!errorEncountered) {
ServiceClient serviceClient = new ServiceClient();
String servicesUrl = this.environment.getProperty("service_url_reports_data");
String servicesName = this.environment.getProperty("service_name_reports_update_fnol");
String serviceUrl = VIPUrlFactory.getServiceUrl(servicesUrl+servicesName);
logger.log(LogLevel.DEBUG, "For update : serviceUrl: "+serviceUrl);
//Option 1: Using Spring RestTemplate :
LinkedMultiValueMap<String,String> headers = new LinkedMultiValueMap<String,String>();
headers.add("Accept","application/json");
headers.add("Content-type","application/json");
List list = new ArrayList<Map<String, String>>(); list.add(formModelData);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<List> requestEntity = new HttpEntity<List>(list, headers);
ResponseEntity<List> fList = restTemplate.exchange(serviceUrl,
HttpMethod.POST,
requestEntity,
List.class);
//Option 2: using org.apache.commons.httpclient.methods.PostMethod; -- Will be commented when option 1 block is uncommented
serviceClient.setParams(formModelData);
serviceClient.setServiceUrl(serviceUrl);
serviceClient.callRestServicePost();
logger.log(LogLevel.DEBUG, "Posting data to service - to execute the update");
}
}
In the above code, option 1 and option 2 block won't be executed simultaneously.
Below is the code block which accepts the Restful call, my server side code.
#RequestMapping(value = "/update", method = RequestMethod.POST)
public void updateMainRptData(#RequestBody Map<String, String> formModelData) throws ReportingIntegrationException,
IOException, JsonMappingException {
String updateStmt = "UPDATE CL_SCRIPTS SET DELETE_IND = #{delete_ind}, SCRIPT_DESC = #{script_desc}, SCRIPT_TXT = #{script_txt}WHERE COMPANY_CD = #{company_cd} AND SCRIPT_NAME = #{script_name}AND PROMPT_ID = #{prompt_id}";
ParameterObjectDTO paramObjDTO = new ParameterObjectDTO();
logger.log(LogLevel.DEBUG,"In Services Web: updateMainRptData()");
if(!formModelData.isEmpty()) {
Set<String> keySet = formModelData.keySet();
StringBuilder sb = new StringBuilder();
for (String key : keySet) {
sb.append(key).append(" -- ").append(formModelData.get(key)).append("\n");
}
logger.log(LogLevel.DEBUG, sb.toString());
}
paramObjDTO.setModalForQuery(formModelData);
paramObjDTO.setUpdateSqlStmt(updateStmt);
maintReportingSvc.updateMaintReport(paramObjDTO);
}
Error Messages I see in browsers is not helpful but my JSON data is valid I believe. Any help is appreciated. Thanks.
Later I changed the signature of the method updateMainRptData and added a returntype and #ResponseBody to resolve this issue.

Spring RestTemplate : get with nullable paramaeter

I'm trying to make a true RestFull service and keeping to the documentation. However I'm stuck now with a problem I can't see a clear answer for. I want to use a filter to query some data from the webservice. The following path is defined on the controller of the webservice
#RequestMapping(value="/rest/postalcode/list/filter?lang={lang}&postalcode={postalcode}&country={country}&city={city}", method = RequestMethod.GET, produces="application/json")
public #ResponseBody JsonPostalCodeList findFilteredPostalCodes(#PathVariable("lang") String lang, #PathVariable("postalcode") String postalcode, #PathVariable("country") Long country, #PathVariable("city") String city, Model model) throws Exception {
}
Then I try to call it with the following method on client side
public JsonPostalCodeList findPostalCodes(
JsonPostalCodeSelectorData selectorData) {
String url = getWebserviceLocation()+"/rest/postalcode/list/filter?lang={lang}&postalcode={postalcode}&country={country}&city={city}";
MbaLog.debugLog(logger,"Calling webservice with url: " + url);
return getRestTemplate().getForObject(url, JsonPostalCodeList.class, selectorData.getContactLanguage(), selectorData.getPostalCode(), selectorData.getCountry(), selectorData.getCity());
}
now selectorData.getPostalCode() can be null for example because , the user didn't fill in a postalcode to filter on. Same can be true for country and city (lang is always filled in). But each time I run it I get an IOException not found (probably due to the null's). I tried once with everything filled in and I go perfectly in my method at service side. So how do you handle such a problem ?
I can solve it by throwing GET out of the window and just put everything in a POST body as a JSONobject mapped with Jackson and problem solved. But then I'm using a POST to fetch data while a GET should be used in pure REST to fetch data.
So RestTemplate and querying services with variable data how to go about it ?
Just took a cold shower and found it out myself :)
I don't have to use pathvariables I can just use request parameters.
#RequestMapping(value="/rest/postalcode/list/filter", method = RequestMethod.GET, produces="application/json")
public #ResponseBody JsonPostalCodeList findFilteredPostalCodes(#RequestParam("lang") String lang, #RequestParam("postalcode") String postalcode, #RequestParam("country") Long country, #RequestParam("city") String city, Model model) throws Exception {
}
and calling it with
#Override
public JsonPostalCodeList findPostalCodes(
JsonPostalCodeSelectorData selectorData) {
String url = getWebserviceLocation()+"/rest/postalcode/list/filter?lang={lang}&postalcode={postalcode}&country={country}&city={city}";
MbaLog.debugLog(logger,"Calling webservice with url: " + url);
return getRestTemplate().getForObject(url, JsonPostalCodeList.class, selectorData.getContactLanguage(), selectorData.getPostalCode(), selectorData.getCountry(), selectorData.getCity());
}

Categories

Resources