I GET NullPointerException with status code : 400
I am pushing data into a JsonObject and then post it to my back end (Spring ) and get the field using Json mapper (data.get("Field name").asText;.
I also tried get(index) and data.path but this return null, where as in the debug console It indicates that Json objects were received, what is it that makes these fields to be null?
Is it because this data is not directly from ng-model, or is it because I have pushed it into json object using Angular, because I am getting 400 erro code.
MY ANGULAR JS :
app.controller("OrderOperationsCtrl", function($scope, $http,$window) {
$http.get(productURL).then(function(response) {
$scope.productData = response.data;
$scope.newData = [];
$scope.total = 0.0;
$scope.sync = function(bool,productData,submit){
if(bool === true){
var numberOrdered = 0;
numberOrdered++;
$scope.total = $scope.total + productData.price;
var newD = $scope.newData.push({
"numberOrdered":numberOrdered,
"customerId":localStorage.getItem('takealot_customer'),
"id":productData.id,
"total":$scope.total
});
$scope.sender = $scope.newData;
console.log(" NewD " + $scope.newData);
}
if(submit === true){
$http.put(orderURL,JSON.stringify($scope.sender)).then(function(response){
if(response.data)
console.log("Order created !");
},function(response){
console.log("Error creating Order !");
console.log(response.status);
});
MY SPRING CONTROLLER UPDATE
public ResponseEntity createOrder(#RequestBody OrderOperations[] operation) throws OrderOperationsNotFoundException, IOException{
logger.info("recieved json String " + operation);
services.createOrder(operation);
return new ResponseEntity(HttpStatus.OK);
}
CONSOLE OUTPUT :
Hibernate: select products0_.id as id1_3_, products0_.category as category2_3_, products0_.description as descript3_3_, products0_.name as name4_3_, products0_.price as price5_3_, products0_.quantity as quantity6_3_, products0_.supplier as supplier7_3_ from products products0_
2017-11-03 11:34:41.689 INFO 10504 --- [nio-8080-exec-9]
c.p.C.OrderOperationsController : recieved json String
[{"numberOrdered":1,"customerId":null,"id":1,"total":78.32,"$$hashKey":"object:17"},
{"numberOrdered":1,"customerId":null,"id":2,"total":156.70999999999998,"$$hashKey":"object:19"},
{"numberOrdered":1,"customerId":null,"id":1,"total":235.02999999999997,"$$hashKey":"object:21"}]
THanks in advance
First of all you dont need to map the json into the OrderOperation Object.
Spring will automatically convert the JSON Object into OrderOperations by passing as Parameter
public ResponseEntity createOrder(#RequestBody OrderOperations operation)
And i think you get the Nullpointer while you parsing the Data
Finally I have got a solution. some weeks ago.
- For those who are still struggling to save multiple objects from JSON array
see below ... I hope this helps someone else.
public List<String> createOrder(#RequestBody OrderOperations[] json) throws OrderOperationsNotFoundException, IOException{
logger.info("recieved json String " + json);
List<String> response = new ArrayList<String>();
for(OrderOperations op : json){
services.createOrder(op);
response.add("saved order : " + op.toString());
}
return response;
}
Related
I wrote:
private RequestBuilder getPostRequest(String api) {
return Rest.post(url + api)
.jsonContent()
.header("wsc-access-key", WowzaAccount.getAccessKey())
.header("wsc-api-key", WowzaAccount.getRestKey());
}
getPostRequest("live_streams").body(json).fetchAsJsonMap(new OnComplete<Response<Map>>() {
#Override
public void completed(Response<Map> v) {
if (v.getResponseCode() == 201) {
// success
Map<String, Object> response = v.getResponseData();
name = (String) response.get("name");
id = (String) response.get("id");
connection_code = (String) response.get("connection_code");
Log.p("WowzaLiveStream -> (Code 201) Successfully created live stream with name " + name, Log.DEBUG);
onComplete.completed(instance);
} else if (v.getResponseCode() == 401) {
Log.p("WowzaLiveStream -> (Code 401) Unauthorized, failed to create live stream with name " + params.name.get(), Log.DEBUG);
onFail.run();
} else if (v.getResponseCode() == 422) {
Log.p("WowzaLiveStream -> (Code 422) Unprocessable Entity, failed to create live stream with name " + params.name.get(), Log.DEBUG);
onFail.run();
} else {
Log.p("WowzaLiveStream -> Unknow response with code " + v.getResponseCode() + ", failed to create live stream with name " + params.name.get(), Log.DEBUG);
onFail.run();
}
}
});
The problem is that when I get a 422 response code my onFail callback is not called. Instead a Dialog appears. I suppose that this dialog is invoked by the default addNetworkErrorListener code in the init(). However... I cannot (and I don't want to) disable the default addNetworkErrorListener code, because I'm writing a new CN1Lib. Instead I need that in this case, and only in this case, the network error listener should not be invoked and instead the failure callback that I wrote should be run.
It's more appropriate, in this case, to call the network error listener only if the Internet connection is lost.
Thank you
You need to explicitly catch the error code callback as the callback might have a different format than the main JSON:
private RequestBuilder getPostRequest(String api) {
return Rest.post(url + api)
.jsonContent()
.header("wsc-access-key", WowzaAccount.getAccessKey())
.header("wsc-api-key", WowzaAccount.getRestKey())
.onErrorCodeJSON(map -> {
// process error response
});
}
I m using Aqueduct 3.0. I need to learn How to capture post request in Aqueduct 3.0?
My Request: http://127.0.0.1:8888/login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjM+oHROYz/YTHnd3NH1XfHRULY0jaHU
Get a Response:
[INFO] aqueduct: GET /login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjM+oHROYz/YTHnd3NH1XfHRULY0jaHU 11ms 404
my channel.dart routing
// TODO: connect to Socket **********
router.route('/login/[:value]').link(() {
return new LoginController();
//..contentType = ContentType.TEXT;
});
my LoginController.dart
import 'package:aqueduct/aqueduct.dart';
import 'package:niyaziapi/niyaziapi.dart';
import 'package:niyaziapi/util/niyaziGetPrivate.dart';
import 'package:niyaziapi/util/niyaziSetPrivate.dart';
class LoginController extends Controller {
String _xCustomerToken;
String _xCustomerName;
String _xPrivate;
String _xResult;
String _xRequestValue;
String _xReply;
#override
Future<RequestOrResponse> processRequest(Request request) async {
String tempData = request.toString();
print("tempDate: $tempData"); // can’t print
try {
if (request.path.variables.containsKey('value')) {
_xPrivate = (request.path.variables['value']).trim();
print("_xPrivate: $_xPrivate");
var decryptedData = await getPrivate(_xPrivate);
var decryptedList = decryptedData.split(":_:");
decryptedData = null;
decryptedData = "Q101:_:" + decryptedList[2].toString() + ":_:" + decryptedList[3].toString();
print(decryptedData);
var socket = await Socket.connect('192.168.1.22', 1024);
socket.write("$decryptedData\r\n");
await for (var data in socket) {
_xReply = new String.fromCharCodes(data).trim();
var list = _xReply.split(":_:");
_xCustomerToken = list[2].toString();
_xCustomerName = list[3].toString();
});
_xResult = "$_xCustomerToken:_:$_xCustomerName";
var encryptedData = await setPrivate(_xResult);
return new Response.ok("$encryptedData");
}
} else {
return new Response.ok("404: Wrong Request");
}
} catch (e) {
return new Response.ok("404: $e.errorMessage");
}
}
}
when I testing I found that my code works. Only reason that I am sending 3DES data and has + and / character in it.
If you look at closely in first request, there is a + and / character in data which give me an error.
/login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjM+oHROYz/YTHnd3NH1XfHRULY0jaHU 19ms 404
on the other hand if I remove those character than I get perfect response.
/login/ziD7v0Ul99vmNWnxJRxZIiTY4zakNoq8GjMoHROYzYTHnd3NH1XfHRULY0jaHU 13 ms 200
So, question comes how to send encrypted (3DES) data into aqueduct without getting any error?
Going to Like Aqueduct twice :)
It was very simple:
var _xPrivate = (request.path.variables['value']).trim(); change to:
var _xPrivate = request.path.remainingPath;
print("request: $_xPrivate");
From my rest client, i am hitting a web service and getting my response in the form of String {"code":"00000","msg":"Success"> . Now I am converting this in the form of JSONObject which i can then use further. But i am not able to. Below is the code i am using . Please guide.
private ResponseEntity<String> test()
{
final String uri = "URL";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
System.out.println(result);
//This part is not working.
try {
JSONObject arr = new JSONObject((result));
for (int i = 0; i < arr.length(); i++) {
JSONObject abc = arr.getJSONObject(i);
System.out.println("test1 : " + abc.getString("test1"));
System.out.println("test2 : " + abc.getString("test2"));
System.out.println("test3 : " + abc.getString("test3"));
}
} catch (Exception e) {
}
return result;
}
Instead of converting to a generic JSONObject, you should create a class matching your response.
Spring will map the response to your model class using Jackson(behind the scenes). There is no need for converting it yourself.
So Let's say, you create a class
class Response {
String code;
String message:
//Gettes and Setters
}
Now you can change your code a bit like this
ResponseEntity<Response> result = restTemplate.exchange(uri, HttpMethod.GET, entity, Response.class);
Now if you useresult.getBody(), this would give your Response object, which you can use
One form is using JSONObject
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
<scope>${scope}</scope>
</dependency>
import org.json.simple.JSONObject;
JSONObject json = new JSONObject();
json.put("key1", value1);
json.put("key2", value2);
JSP code --- I have used Angular js in scripting. The issue is that the form Data is not being sent to the resource method in portlet class. Also when I log the form data in console it displays empty. It takes up JSON data and append into form data. the json value is passed as transaction data { 1: "1", purchaseRegisterId: 33411, undefined: "book3.jpg" } and documentId is passed as documentId :: documents33411. these data is taken from the console log.
$scope.savePurchaseRegisterEntry=function(documentId, json){
console.log("documentId :: "+documentId);
//console.log("json");
console.log(json);
var fd = new FormData();
fd.append('auditDetailesId',$scope.auditDetailesId);
console.log(fd);
var documentcollection=[];
for(var key in json){
fd.append(key,json[key]);
if("purchaseRegisterId"!=key && key!=='undefined'){
documentcollection.push(key);
}
}
$.each( $("#"+documentId), function( input_key, input_value ) {
$.each( input_value.files, function( file_key, file_value ) {
fd.append('myFiles', file_value);
});
});
fd.append("documentCollectionIds",documentcollection.join(','));
console.log("fd");
console.log(fd);
console.log("documentcollectionids :: "+documentcollection.join(','))
//return false;
$http({
method:'POST',
url:'<%=savePurchaseRegisterEntry%>',
type:"json",
data:fd,
headers: {'Content-Type': undefined},
transformRequest:angular.identity
}).success(function(response){
console.log(response);
var response=angular.fromJson(response.selectedTransactionList);
$scope.dataList=angular.fromJson(response.data);
$scope.ariaValuenow =response.currentCount;
$scope.ariaValuemin=0;
$scope.ariaValueMax=response.data[0]['maxInputDocCount']* response.total;
$scope.percentageComplete=(($scope.ariaValuenow - $scope.ariaValuemin) * 100) / ($scope.ariaValueMax - $scope.ariaValuemin);
if($scope.percentageComplete==100){
$scope.saveStatus();
$scope.readyForAudit=true;
}else{
$scope.readyForAudit=false;
}
});
}
Resurces Method --- the data is being fetched here to store the values into database table.
public void savePurchaseRegisterEntry(ResourceRequest req,
ResourceResponse res) throws SystemException, IOException {
_log.info("i am in savePurchaseRegisterEntry!!!");
ThemeDisplay themeDisplay = (ThemeDisplay) req
.getAttribute(WebKeys.THEME_DISPLAY);
_log.info(" ----- " + ParamUtil.getString(req, "purchaseRegisterId"));
_log.info(" ----- " + ParamUtil.getLong(req, "purchaseRegisterId"));
String documentCollectionIds=ParamUtil.getString(req, "documentCollectionIds");
String[] documentCollectionIdArray=documentCollectionIds.split(",");
MultiDocumentUploadUtil.createFolder(req, themeDisplay ,ParamUtil.getLong(req, "purchaseRegisterId") , "purchaseRegisterId");
String fileIds=MultiDocumentUploadUtil.fileUpload(themeDisplay, req);
_log.info("fileIds : "+fileIds);
long purchaseRegisterId =ParamUtil.getLong(req, "purchaseRegisterId");
for(String s : documentCollectionIdArray){
System.out.println("s is "+Long.parseLong(s));
_log.info(Long.parseLong(s)+"long sssss "+ s+" s :: "+ParamUtil.getLong(req, s));
_log.info(Long.valueOf(s)+"long sssss "+ s+" s :: "+ParamUtil.getLong(req, s));
AuditDocumentCollection adc= AuditDocumentCollectionLocalServiceUtil.fetchByPurchaseRegisterIdAnddocumentCollectionId(purchaseRegisterId, Long.valueOf(s));
AuditDocumentCollection adc1=adc;
if(adc==null){
adc=AuditDocumentCollectionLocalServiceUtil.createAuditDocumentCollection(CounterLocalServiceUtil.increment());
}
adc.setDocumentCollectionId(Long.valueOf(s));
adc.setPurchaseRegisterId(purchaseRegisterId);
adc.setValue(ParamUtil.getLong(req, s));
if(adc1==null){
adc.setCreateDate(new Date());
adc.setCreatedBy(themeDisplay.getUserId());
adc.setModifiedBy(themeDisplay.getUserId());
adc.setModifiedDate(new Date());
AuditDocumentCollectionLocalServiceUtil.addAuditDocumentCollection(adc);
}else{
adc.setModifiedBy(themeDisplay.getUserId());
adc.setModifiedDate(new Date());
AuditDocumentCollectionLocalServiceUtil.updateAuditDocumentCollection(adc);
}
}
PurchaseRegister purchaseRegister=PurchaseRegisterLocalServiceUtil.fetchPurchaseRegister(purchaseRegisterId);
if(!fileIds.isEmpty()){
purchaseRegister.setDocumentIds(fileIds);
}
PurchaseRegisterLocalServiceUtil.updatePurchaseRegister(purchaseRegister);
JSONObject jsonobject = JSONFactoryUtil.createJSONObject();
long auditDetailesId=ParamUtil.getLong(req, "auditDetailesId");
jsonobject.put("selectedTransactionList",CommonUtil.getAuditProcessInfo( auditDetailesId));
PrintWriter out = res.getWriter();
out.write(jsonobject.toString());
out.flush();
out.close();
}
I suppose the data present in form data is being sent to resource method. it is not taking documentCollectionIds and its empty. The error I get is this,
[http-bio-3030-exec-10][PurchaseRegisterPortlet:644] i am in savePurchaseRegisterEntry!!!
05:58:34,050 INFO [http-bio-3030-exec-10][PurchaseRegisterPortlet:648] -----
05:58:34,050 INFO [http-bio-3030-exec-10][PurchaseRegisterPortlet:649] ----- 0
Folder is already Exist
fileEntryList.toArray().toString() :: 34529
05:58:34,255 INFO [http-bio-3030-exec-10][PurchaseRegisterPortlet:657]fileIds : 34529
Exception in thread "liferay/document_library_image_processor-3"05:58:34,256 ERROR [DispatcherPortlet:559] Could not complete request
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:453)
at java.lang.Long.parseLong(Long.java:483)
at com.auditcompliance.purchaseregister.controller.PurchaseRegisterPortlet.savePurchaseRegisterEntry(PurchaseRegisterPortlet.java:660)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
check your file first the typscript file of your component if you give
it exactly the type Number, then your service
Or if it's through the html file of your component that you give it
the right type in parameter
For me it was in the html file that I gave him another type
different from number
I am not good with Web API. Here is my problem. I send an Json serialized object from my Windows Form Application. The object is an Entity table. When I do a get response it returns a 500 server error. Basically I plan to have multiple post methods in one controller which I may not be doing right. So I need you guys to guide me on what I have been doing wrong.
Here is my Controller:
[ResponseType(typeof(HttpWebResponse)), HttpPost, ActionName("MerchandiseApi")]
public HttpResponseMessage PostMain(IList<IMF_Main> mainFromConsolidator)
{
if (!ModelState.IsValid)
return Request.CreateResponse(HttpStatusCode.BadRequest, 2);
using (var anthill = new AnthillConsolidatorEntities())
{
var main = new IMF_Main();
foreach (var item in mainFromConsolidator)
{
main.BrandID = item.BrandID;
main.ItemID = item.ItemID;
main.CategoryID = item.CategoryID;
main.SubCategoryID = item.SubCategoryID;
main.ClassID = item.ClassID;
main.GenderID = item.GenderID;
main.CoaID = item.CoaID;
main.SubCoaID = item.SubCoaID;
main.First_SRP = item.First_SRP;
main.Current_SRP = item.Current_SRP;
main.Previous_SRP = item.Previous_SRP;
main.isSenior = item.isSenior;
main.isActive = item.isActive;
main.DateCreated = item.DateCreated;
anthill.IMF_Main.Add(main);
anthill.SaveChanges();
}
}
return Request.CreateResponse(HttpStatusCode.OK, 1);
}
Here's my WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "MerchandiseApi",
routeTemplate: "api/{controller}/{action}"
);
}
Here is where the Uri gets built: I have 2 more tables to send but I will start with this. This goes to my first Post method to the server
var jsonMain = JsonConvert.SerializeObject(consolidatorEntities.IMF_Main, Formatting.None);
HttpPost("http://localhost:50826/api/Merchandise/PostMain", jsonMain) == 1.ToString()
public string HttpPost(string uri, string json)
{
string content = "";
try
{
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.Accept = "application/json";
request.ContentType = "application/json";
byte[] bodyBytes = Encoding.UTF8.GetBytes(json);
request.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
request.GetRequestStream().Close();
var response = (HttpWebResponse)request.GetResponse();
var sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncod
ing("UTF-8"));
content = sr.ReadToEnd();
sr.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error sending data to Anthill \nException: " + ex, "Monytron - Consolidator", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return content;
}
Problem
The main problem is with your routing. Routes will check in order so when you post a request to http://localhost:50826/api/Merchandise/PostMain and you have these routes in order:
"api/{controller}/{id}"
"api/{controller}/{action}"
So the first route will match:
If your PostMain method is the only action with [HttpPost], then mainFromConsolidator will be null in your foreach loop you will receive a NullReferenceException that result in a 500 error.
If you have multiple method decorated with [HttpPost], then the call is ambiguous between those actions and you will receive an InvalidOperationExpception with "Multiple actions were found that match the request" message that result in a 500 error.
The other problem is you are using an ActionName("MerchandiseApi") but didn't post to that action.
Solution
You can use multiple solutions. As an option you can define only one route:
"api/{controller}/{action}/{id}"
This way you can create a controller that contains actions like these:
public class SomeController
{
// matches GET /api/some/action1
[HttpGet]
public HttpResponseMessage Action1()
// matches GET /api/some/action2/5
[HttpGet]
public HttpResponseMessage Action2(int id)
// matches POST /api/some/action3
[HttpPost]
public HttpResponseMessage Action3(SomeType someParameter)
// matches POST /api/some/action4
[HttpPost]
public HttpResponseMessage Action4(SomeType someParameter)
}
Anyway if you decide to define multiple routes, pay attention that routes will match in order and also if you used ActionName attribute, then use that name in url to call that action.