On parsing gson.toJson(obj) giving null - java

wWhen I am passing object of local-inner-class ShipAddress to toJson() method of Gson class this is returning null on parsing it.
public class CrusialDateRest {
public String getShippingAddressesDetails() {
Gson gson = new GsonBuilder().create();
try {
Collection<ImplAddress> savedAddressBeans = new ArrayList<ImplAddress>();
Collection<CtFlexField> countryFields = new ArrayList<CtFlexField>();
Collection<CtFlexField> debitorFields = new ArrayList<CtFlexField>();
class ShipAddress{
Collection<ImplAddress> savedAddressBean = new ArrayList<ImplAddress>();
Collection<CtFlexField> countryField = new ArrayList<CtFlexField>();
Collection<CtFlexField> debitorField = new ArrayList<CtFlexField>();
ShipAddress( Collection<ImplAddress> savedAddressBeans, Collection<CtFlexField> countryFields,Collection<CtFlexField> debitorFields){
savedAddressBean=savedAddressBeans;
countryField=countryFields;
debitorField=debitorFields;
}
}
String addrId= XmlParser.getNodeValue(address, Statics.BUYFLOW_NAMESPACE, "AddressId");
String addrStreet1 = XmlParser.getNodeValue(address, Statics.BUYFLOW_NAMESPACE, "AddrStreet1");
String addrStreet2 = XmlParser.getNodeValue(address, Statics.BUYFLOW_NAMESPACE, "AddrStreet2");
String addrStreet3 = XmlParser.getNodeValue(address, Statics.BUYFLOW_NAMESPACE, "AddrStreet3");
ImplAddress impladdress = new ImplAddress();
impladdress.setAddressId(addrId);
impladdress.setAddrStreet1(addrStreet1);
impladdress.setAddrStreet2(addrStreet2);
impladdress.setAddrStreet3(addrStreet3);
savedAddressBeans.add(impladdress);
}
CtFlexField[] flexField = flexFields.getFlexField();
for (CtFlexField flex : flexField) {
if(flex.getBundle().equalsIgnoreCase("Countries")){
countryFields.add(flex);
}
else if(flex.getBundle().equalsIgnoreCase("CommonBundle")){
debitorFields.add(flex);
}
}
jsonResponse = gson.toJson(new ShipAddress(savedAddressBeans,countryFields,debitorFields));
OUT.debug("jsonResponse--"+jsonResponse);
} catch (Exception e) {
OUT.error("rest method getShippingAddresses error", e);
}
return jsonResponse;
}
}
Should I make inner class outside method?
Or is this a serialization issue?

It's most likely a visibility issue.
Either move ShipAddress into its own class file, or make it a public static inner class.
Note that public static classes cannot be declared inside of methods, you would have to move the class out of getShippingAddressDetails()method.

Related

unreported exception ParseException; must be caught or declared to be thrown -- JAVA Error

I am building a Java app in JSF that makes a request to an API gets a JSON and fills a table with the JSON info...
This is the code:
#ManagedBean(name = "logic", eager = true)
#SessionScoped
public class Logic {
static JSONObject jsonObject = null;
static JSONObject jo = null;
static JSONArray cat = null;
public void connect() {
StringBuilder sb = new StringBuilder();
try {
URL url = new URL("xxx");
URLConnection yc = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while((inputLine = in.readLine())!= null){
System.out.println(inputLine);
sb.append(inputLine+"\n");
in.close();
}
}catch(Exception e) {System.out.println(e);}
try {
JSONParser parser = new JSONParser();
jsonObject = (JSONObject) parser.parse(sb.toString());
cat = (JSONArray) jsonObject.get("mesaje");
jo = (JSONObject) cat.get(0);
jo.get("cif");
System.out.println(jo.get("cif"));
}catch(Exception e){System.out.println(e);}
}
private String cif;
final static private ArrayList<Logic> logics = new ArrayList<Logic>(Arrays.asList(new Logic(jo.get("cif").toString())));
public ArrayList<Logic> getLogics() {
return logics;
}
public Logic() {
}
public Logic(String cif) throws ParseException {
this.cif = cif;
connect();
}
public String getCif() {
return cif;
}
public void setCif(String cif) {
this.cif = cif;
}
}
On line 67 -> final static private ArrayList<Logic> logics = new ArrayList<Logic>(Arrays.asList(new Logic(jo.get("cif").toString())));
it gives me this error in Netbeans: unreported exception ParseException; must be caught or declared to be thrown.
I tried surrounding it in try catch but it gives other errors in other parts of code...what can I do so I can run app ?
Thanks in advance
From what I understand, you tried something like
try {
final static private ArrayList<Logic> logics = new ArrayList<Logic>(Arrays.asList(new Logic(jo.get("cif").toString())));
} catch (Exception e) {
e.printStackTrace();
}
The problem is, that line is not inside a method, and you can't use try...catch there.
A quick way to solve this is to put that initialization in a static block
public class Logic {
final static private ArrayList<Logic> logics;
static {
try {
logics = new ArrayList<Logic>(Arrays.asList(new Logic(jo.get("cif").toString())));
} catch (Exception e) {
e.printStackTrace();
}
}
// rest of your class...
}
But honestly I have to wonder why you declared logics as static. It's not apparent from the rest of your code. Also, I see you have a non-static getLogics() method. So I'd say, if there's really no reason to declare it as static, just make it non-static and initialize it in the constructor, where you can use try...catch to your heart's content.

Getting value from json item in java

I have a json file, for example:
{
"A":"-0.4",
"B":"-0.2",
"C":"-0.2",
"D":"X",
"E":"0.2",
"F":"0.2",
"J":"0.3"
}
I want return each element of a list json when I call it via my function.
I did a function to do this:
public JSONObject my_function() {
JSONParser parser = new JSONParser();
List<JSONObject> records = new ArrayList<JSONObject>();
try (FileReader reader = new FileReader("File.json")) {
//Read JSON file
Object obj = parser.parse(reader);
JSONObject docs = (JSONObject) obj;
LOGGER.info("read elements" + docs); // it display all a list of a json file like this: {"A":"-0.4","B":"-0.2","C":"-0.2","D":"X","E":"0.2","F":"0.2","J":"0.3"}
for (int i = 0; i < docs.size(); i++) {
records.add((JSONObject) docs.get(i));
System.out.println((records)); // it return null
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
LOGGER.info("The first element of a list is:" +records.get(0)); // return null
return records.get(0);
How can I change my function to return the value of each element in a json file.
For example, when I call my_function:
my_function.get("A") should display -0.4
Thank you
First you need a Class for mapping
public class Json {
private String a;
private String b;
private String c;
private String d;
private String e;
private String f;
private String j;
//getters and setters
}
Then in your working class
ObjectMapper mapper = new ObjectMapper();
//JSON from file to Object
Json jsn = mapper.readValue(new File("File.json"), Json.class);
then you can use that object in a usual way...
here is the dependency I used
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
Reference
In Java you can use only class`s methods, as I know.
If you want to get your second element by its first, you should in your class create 2 methods like
class Main {
Map<String, String> records = new HashMap<>();
public JSONObject my_function() {
// your realization where you should insert your pairs into Map.
}
public String get(String firstElement){
return map.getValue(firstElement);
}
}
class someOtherClass {
Main main = new Main();
main .my_function();
main .get("A");
}

how iterate over Object arrays with java reflection

I want to iterate over Object[] within a class with Reflection
this is my class :
public class Lab {
public Browser[] browser;
}
class Browser {
String url;
}
I want to reach browser[] from the Lab class at index 3 and check value of url
You can achieve that with something like the following snippet:
public boolean urlEquals(Lab lab, String other){
try{
Field browsersField = Lab.class.getDeclaredField("browsers");
Object browsers = browsersField.get(lab);
Object browser = Array.get(browsers, 3);
Field urlField = Browser.class.getDeclaredField("url");
urlField.setAccessible(true);
Object url = urlField.get(browser);
return url.equals(other);
} catch(Exception e){ // probably catch specific exceptions than all
throw new IllegalStateException(e);
}
}
Maybe in this way:
public class Lab
{
public Browser[] browser;
public static void main(String[] args)
{
Lab myLabInstance = new Lab();
myLabInstance.browser = new Browser[] { new Browser(), new Browser(), new Browser(), new Browser(), };
for (Field field : Lab.class.getDeclaredFields())
{
System.out.println(field.getName());
if (field.getName().equalsIgnoreCase("browser"))
{
field.setAccessible(true);
Browser[] browsers = (Browser[]) field.get(myLabInstance);
System.out.println(browsers[3].url.equals("myvalue"));
}
}}}
class Browser
{
public String url = "hallo";
}

Creating stub for dependence class's under test

Good day, everyone! I have a little question about testing and generating a stub for dependence through reflection. So let's assume I have a class named UnderTest:
class UnderTest{
/*field*/
SomeLogic someLogic;
/*method, that i testing*/
List<MyObject> getCalculatedObjects(params) {/*logic,based on result getSomeStuff of someLogic*/ }
}
class SomeLogic {
List<String> getSomeStuff(String param) { /*Some complex and slow code, actually don't want test this code, and want to use some reflection invocation handler*/ }
}
For me it's important to not change legacy code, which doesn't design for testing. And i don't have any reason, except testing to make SomeLogic as an interface and so on.
I can't remember how to handle method invocation of someLogic using reflection. But google search isn't helping me.
Class MainAPI is... main api of my module. NetworkProvider long open stream operation, that's why i want to stub it, on my local files. But don't using directly reference on NetworkProvider. Again sorry for my English.
public class MainAPI {
private final XPath xPath;
private final ItemParser itemParser;
private final ListItemsParser listItemsParser;
private final DateParser dateParser;
private final HtmlCleanUp htmlCleanUp;
private final NetworkProvider networkProvider;
public MainAPI(XPath xPath, ItemParser itemParser, ListItemsParser listItemsParser, DateParser dateParser, HtmlCleanUp htmlCleanUp, NetworkProvider networkProvider) {
this.xPath = xPath;
this.itemParser = itemParser;
this.listItemsParser = listItemsParser;
this.dateParser = dateParser;
this.htmlCleanUp = htmlCleanUp;
this.networkProvider = networkProvider;
}
public MainAPI() throws XPathExpressionException, IOException {
dateParser = new DateParser();
xPath = XPathFactory.newInstance().newXPath();
networkProvider = new NetworkProvider();
listItemsParser = new ListItemsParser(xPath, dateParser, item -> true);
itemParser = new ItemParser(xPath, dateParser, networkProvider);
htmlCleanUp = new HtmlCleanUpByCleaner();
}
public List<Item> getItemsFromSessionParsing(SessionParsing sessionParsing) {
listItemsParser.setCondition(sessionParsing.getFilter());
List<Item> result = new ArrayList<>();
Document cleanDocument;
InputStream inputStream;
for (int currentPage = sessionParsing.getStartPage(); currentPage <= sessionParsing.getLastPage(); currentPage++) {
try {
inputStream = networkProvider.openStream(sessionParsing.getUrlAddressByPageNumber(currentPage));
} catch (MalformedURLException e) {
e.printStackTrace();
break;
}
cleanDocument = htmlCleanUp.getCleanDocument(inputStream);
List<Item> list = null;
try {
list = listItemsParser.getList(cleanDocument);
} catch (XPathExpressionException e) {
e.printStackTrace();
break;
}
for (Item item : list) {
inputStream = null;
try {
inputStream = networkProvider.openStream("http://www.avito.ru" + item.getUrl());
} catch (MalformedURLException e) {
e.printStackTrace();
break;
}
cleanDocument = htmlCleanUp.getCleanDocument(inputStream);
try {
item.setDescription(itemParser.getDescription(cleanDocument));
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
result.addAll(list);
}
return result;
}
}
public class NetworkProvider {
private final ListCycleWrapper<Proxy> proxyList;
public NetworkProvider(List<Proxy> proxyList) {
this.proxyList = new ListCycleWrapper<>(proxyList);
}
public NetworkProvider() throws XPathExpressionException, IOException {
this(new ProxySiteParser().getProxyList(new HtmlCleanUpByCleaner().getCleanDocument(new URL("http://www.google-proxy.net").openStream())));
}
public int getSizeOfProxy() {
return proxyList.size();
}
public InputStream openStream(String urlAddress) throws MalformedURLException {
URL url = new URL(urlAddress);
while (!proxyList.isEmpty()) {
URLConnection con = null;
try {
con = url.openConnection(proxyList.getNext());
con.setConnectTimeout(6000);
con.setReadTimeout(6000);
return con.getInputStream();
} catch (IOException e) {
proxyList.remove();
}
}
return null;
}
}
All the dependencies of your class to tests are injectable using its constructor, so there shouldn't be any problem to stub these dependencies and injecting the stubs. You don't even need reflection. For example, using Mockito:
NetworkProvider stubbedNetworkProvider = mock(NetworkProvider.class);
MainAPI mainApi = new MainAPI(..., stubbedNetworkProvider);
You can also write a stub by yourself if you want:
NetworkProvider stubbedNetworkProvider = new NetworkProvider(Collections.emptyList()) {
// TODO override the methods to stub
};
MainAPI mainApi = new MainAPI(..., stubbedNetworkProvider);

References in Java constructor

This is the first version of my code :
public class ListSchedule implements ListInterface {
private ArrayList<Schedule> list;
private String cookie;
public ListSchedule() {
this.list = new ArrayList<Schedule>();
}
public ArrayList<Schedule> getList() {
return list;
}
}
In another class, I made this call :
protected final ListSchedule parse(String jsonString)
throws CustomException {
ListSchedule list = new ListSchedule();
JSONArray schedulesArray;
try {
// Convert the response to a JSONObject
JSONObject json = new JSONObject(jsonString);
try {
int errorCode = json.getInt("error");
// Check if there is no error from FilBleu server
if (errorCode > 0) {
throw new CustomException(
CustomException.ERROR_FILBLEU,
"DataAccessObject", "Server error "
+ json.getInt("subError"));
}
try {
String cookie = json.getString("cookie");
list = new ListSchedule(cookie);
} catch (JSONException e) {
throw new CustomException(CustomException.JSON_FORMAT,
"DataAccessObject", "No cookie value");
}
schedulesArray = json.getJSONArray("schedules");
// NullPointerException with the line below
Log.d("DAO", list.getList().toString());
parseSchedulesArray(list, schedulesArray);
} catch (JSONException e) { // Unable to get the error code
throw new CustomException(CustomException.JSON_FORMAT,
"DataAccessObject", "Bad JSON format ("
+ e.getMessage() + ")");
}
} catch (JSONException e) { // Unable to convert response
throw new CustomException(CustomException.JSON_FORMAT,
"DataAccessObject", "Bad JSON format ("
+ e.getMessage() + ")");
}
return list;
}
then I had a NullPointerException from the line Log.d("DAO", list.getList().toString());. So I tried another solution. As you can see, the only difference is the initialization of the list property :
public class ListSchedule implements ListInterface {
private ArrayList<Schedule> list = new ArrayList<Schedule>();
private String cookie;
public ListSchedule() {
}
public ArrayList<Schedule> getList() {
return list;
}
}
and the NullPointerException was never thrown again...
I don't really understand the difference between the two ways of initializing the list property. Can somebody give me a hint please ?
I am speculating that the following constructor exists in your code base :
public ListSchedule(String cookie) {
this.cookie = cookie;
}
and what you need is the following:
public ListSchedule(String cookie) {
this.cookie = cookie;
this.list = new ArrayList<Schedule>();
}
This is further validated by the invocation of this line in your program:
list = new ListSchedule(cookie);
Notice how you don't initialize the list in the second constructor. Also you start by invoking the default constructor, but you later reassign the pointer to the object into what gets created from the String constructor of ListSchedule.
You code is calling this constructor:
list = new ListSchedule(cookie);
Which to me, does not call the one that initializes your ArrayList<Schedule> and that explains the NullReferenceException

Categories