I have a Request Class that contains another class object. Now I want to parse a nested JSON as Request Class Object.
I am trying using ObjectMapper but its throwing exceptions. Please help me to do that using java Jackson.
{
"filters":[
{
"key":"CustomerId",
"op":"=",
"value" : "1"
},
{
"key":"userName",
"op":"=",
"value" : "admin"
}
],
"startIndex" : 1,
"size" : 10,
"OrderBy" :
{
"propertyId" : "userName",
"Desc" : false
},
"TimeRange" : {
"startTimestamp" : 1,
"endTimestamp" :10
}
}
Logic:
public static class OrderBy {
private String propertyId;
private boolean desc = true;
}
class TimeRange {
private Long startTimestamp;
private Long endTimestamp;
}
class Filter {
private String propertyId;
private String op;
private Object value;
}
public class Request {
private List<Filter> filters;
private TimeRange timeRange;
private OrderBy orderBy;
private int startIndex = 0;
private int size = 20;
}
I give you a Jaskson Util Tools class.
package com.jackson.utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* The class JacksonUtil
*
* json字符与对像转换
*
* #version: $Revision$ $Date$ $LastChangedBy$
*
*/
public final class JacksonUtil {
public static ObjectMapper objectMapper;
/**
* 使用泛型方法,把json字符串转换为相应的JavaBean对象。
* (1)转换为普通JavaBean:readValue(json,Student.class)
* (2)转换为List,如List<Student>,将第二个参数传递为Student
* [].class.然后使用Arrays.asList();方法把得到的数组转换为特定类型的List
*
* #param jsonStr
* #param valueType
* #return
*/
public static <T> T readValue(String jsonStr, Class<T> valueType) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.readValue(jsonStr, valueType);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* json数组转List
* #param jsonStr
* #param valueTypeRef
* #return
*/
public static <T> T readValue(String jsonStr, TypeReference<T> valueTypeRef){
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.readValue(jsonStr, valueTypeRef);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 把JavaBean转换为json字符串
*
* #param object
* #return
*/
public static String toJSon(Object object) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.writeValueAsString(object);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Now ,you can use blow code covert to Request :
String userBeanToJson = "your json string";//please replace this for your need json
Request jsonToUserBean = JacksonUtil.readValue(userBeanToJson, Request.class);
Hope it is useful for you.
Related
am not able to make SFtp download continuously....0 Kb files are getting downloaded in between..i have used VFS2. Though the same happens in windows, once I refresh the folder,the files are getting filled....but not in Ubuntu...can someone help me with this..
package com.softwareag.webmastersperformer.common.model;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.softwareag.webmastersperformer.common.exception.ActionExecutionFailedException;
import com.softwareag.webmastersperformer.common.exception.InvalidDataException;
/**
* This class extends from AbstractAction by providing specific implementation
* for SFTP action type.
* #author : YEJ
*/
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(propOrder = {
"fileTransferMethod", "serverHostName", "serverSFTPPort",
"serverRelativePath", "fileName", "localFilePath", "basicSettings",
"advancedSettings"
})
public class SftpAction implements IAction {
private String fileTransferMethod;
private String serverHostName;
private int serverSFTPPort;
private String serverRelativePath;
private String fileName;
private String localFilePath;
#XmlJavaTypeAdapter(GenericMapAdapter.class)
private Map<String, Object> basicSettings;
#XmlJavaTypeAdapter(GenericMapAdapter.class)
private Map<String, Object> advancedSettings;
#XmlTransient
private ActionBean parent;
#XmlTransient
private static final Logger LOG = LoggerFactory.getLogger(SftpAction.class
.getName());
#XmlTransient
private FileObject localFile;
#XmlTransient
private FileObject remoteFile;
#XmlTransient
private static StandardFileSystemManager manager;
#XmlTransient
private int i = 0;
// Initializing file manager. This manager object is made one per class as
// we
// cannot have more than one instance of this class instance.
static {
try {
manager = new StandardFileSystemManager();
manager.init();
} catch (FileSystemException ex) {
// Need to log this properly
ex.printStackTrace();
}
}
/**
* Constructor.
*/
public SftpAction() {
super();
this.fileTransferMethod = "put";
this.serverHostName = "";
this.serverSFTPPort = 0;
this.serverRelativePath = "";
this.fileName = "";
this.localFilePath = "";
}
/**
* Constructor.
* #param parent : ActionBean
* #param fileTransferMethod : File transfer method [put/get]
* #param serverHostName : server host name
* #param serverSFTPPort : server SFTP port
* #param localFilePath : local file path
* #throws InvalidDataException : file transfer method is not given
*/
// CHECKSTYLE:OFF
public SftpAction(final ActionBean parent, final String fileTransferMethod,
final String serverHostName, final int serverSFTPPort,
final String serverRelativeFtpPath, final String fileName,
final String localFilePath, final Map<String, Object> basicSettings)
throws InvalidDataException {
// CHECKSTYLE:ON
if (fileTransferMethod == null
|| fileTransferMethod.trim().length() == 0) {
throw new InvalidDataException(
"File transfer method cannot be null or empty");
}
System.out.println("================================================SFTPACTION() " + serverHostName);
this.setParent(parent);
this.setFileTransferMethod(fileTransferMethod);
this.setServerHostName(serverHostName);
this.setServerSFTPPort(serverSFTPPort);
this.setServerRelativePath(serverRelativeFtpPath);
this.setFileName(fileName);
this.setLocalFilePath(localFilePath);
this.setBasicSettings(basicSettings);
this.createClient();
}
/**
* Create a client.
* #throws InvalidDataException : InvalidDataException
*/
public final void createClient() throws InvalidDataException {
try {
if (fileTransferMethod.equalsIgnoreCase("put")) {
final File file = new File(this.localFilePath + File.separator
+ this.fileName);
if (!file.exists()) {
throw new RuntimeException("Error: Local file "
+ file.getAbsolutePath() + " not found");
}
try {
// Put : Create local file object
localFile = manager.resolveFile(file.getAbsolutePath());
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
// Get : Create remote file object
// remoteFile = manager.resolveFile(
// createConnectionString(
// (this.serverHostName + ":" + this.serverSFTPPort), this
// .getBasicSettings().get(Constants.USERNAME)
// .toString(),
// this.getBasicSettings().get(Constants.PASSWORD)
// .toString(), (this.serverRelativePath
// + File.separator + this.fileName)),
// createDefaultOptions());
remoteFile = manager.resolveFile(
createConnectionString(
"10.60.24.218:9876", "perfuser", "manage", ("1MB.txt")),
createDefaultOptions());
}
} catch (FileSystemException ex) {
ex.printStackTrace();
}
}
/**
* {#inheritDoc}
*/
#Override
public final boolean execute() throws ActionExecutionFailedException {
if (getFileTransferMethod().equalsIgnoreCase("put")) {
this.put();
} else {
this.get();
}
return true;
}
// Method to upload a file in Remote server
public void put() {
try {
// Create remote file object
remoteFile = manager
.resolveFile(
createConnectionString(
(this.serverHostName + ":" + this.serverSFTPPort), this
.getBasicSettings().get(Constants.USERNAME)
.toString(),
this.getBasicSettings().get(Constants.PASSWORD)
.toString(), (this.serverRelativePath + "/"
+ this.fileName + "_" + i++)),
createDefaultOptions());
// Copy local file to sftp server
remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Download file function:
public void get() {
try {
String downloadFilePath = this.localFilePath + File.separator
+ this.fileName + "_" + i++;
// Create local file object
localFile = manager.resolveFile(downloadFilePath);
// Copy local file to sftp server
localFile.copyFrom(remoteFile, Selectors.SELECT_SELF);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* {#inheritDoc}
*/
#Override
public final ActionBean getParent() {
return this.parent;
}
/**
* #return the fileTransferMethod
*/
public final String getFileTransferMethod() {
return this.fileTransferMethod;
}
/**
* #return the serverHostName
*/
public final String getServerHostName() {
return this.serverHostName;
}
public final int getServerSFTPPort() {
return this.serverSFTPPort;
}
/**
* #return the localFilePath
*/
public final String getLocalFilePath() {
return this.localFilePath;
}
/**
* #return the local file name
*/
public final String getFileName() {
return this.fileName;
}
/**
* {#inheritDoc}
*/
#Override
public final String getActionName() {
return this.parent.getActionName();
}
/**
* {#inheritDoc}
*/
#Override
public final String getActionDescription() {
return this.parent.getDescription();
}
/**
* {#inheritDoc}
*/
#Override
public final ActionType getActionType() {
return this.parent.getActionType();
}
#Override
public final Map<String, Object> getBasicSettings() {
return this.basicSettings;
}
#Override
public final Map<String, Object> getAdvancedSettings() {
return this.advancedSettings;
}
#Override
public final Map<String, ArrayList<String>> getParameterisedData() {
// TODO Auto-generated method stub
return null;
}
#Override
public final String getPayloadData() throws IOException {
// TODO Auto-generated method stub
return null;
}
#Override
public final RequestResponseHolder getRequestResponse()
throws ActionExecutionFailedException {
// TODO Auto-generated method stub
return null;
}
#Override
public void addParameter(final String parameterName,
final ArrayList<String> parameterValues) {
// TODO Auto-generated method stub
}
/**
* {#inheritDoc}
*/
#Override
public final void setParent(final ActionBean action)
throws InvalidDataException {
if (null == action) {
throw new InvalidDataException(
"Invalid Parent. ActionBean cannot be null");
}
this.parent = action;
}
/**
* #param fileTransferMethod : file transfer method to set
* #throws InvalidDataException if file transfer method is null or empty
*/
public final void setFileTransferMethod(final String fileTransferMethod)
throws InvalidDataException {
this.fileTransferMethod = fileTransferMethod;
}
/**
* #param serverURL : the server URL to set
* #throws InvalidDataException if server URL is null or empty
*/
public final void setServerHostName(String serverURL)
throws InvalidDataException {
serverURL = "10.60.24.218:9876";
if (serverURL == null || serverURL.trim().length() == 0) {
throw new InvalidDataException("Server URL cannot be null or empty");
}
this.serverHostName = serverURL;
}
public final void setServerSFTPPort(final int serverSFTPPort) {
this.serverSFTPPort = serverSFTPPort;
}
/**
* #param localFilePath : local file path to set
* #throws InvalidDataException if local file null or empty
*/
public final void setLocalFilePath(final String localFilePath)
throws InvalidDataException {
if (localFilePath == null || localFilePath.trim().length() == 0
/* || !(new File(localFilePath).exists()) */) {
throw new InvalidDataException(
"Local file path cannot be null or empty or invalid");
}
this.localFilePath = localFilePath;
}
#Override
public final void setBasicSettings(final Map<String, Object> basicSettings)
throws InvalidDataException {
this.basicSettings = basicSettings;
}
#Override
public final void setAdvancedSettings(
final Map<String, Object> advancedSettings) {
this.advancedSettings = advancedSettings;
}
#Override
public void setPayload(final String payload) throws InvalidDataException {
// TODO Auto-generated method stub
}
#Override
public void modifyURL(final String newHost, final int newPort)
throws InvalidDataException {
// TODO Auto-generated method stub
}
/**
* This method is used to set the new file name from the parameter file for
* each action.
* #param newFileName : new file name
*/
public final void setFileName(final String newFileName) {
this.fileName = newFileName;
}
/**
* {#inheritDoc}
*/
#Override
public final SftpAction copyAction() {
/*
* Cloning the action Note: Cloned action will not contain parameterized
* map
*/
SftpAction clonedAction = null;
try {
clonedAction = new SftpAction();
clonedAction.setParent(this.getParent());
clonedAction.setFileTransferMethod(this.getFileTransferMethod());
clonedAction.setServerHostName(this.getServerHostName());
clonedAction.setServerSFTPPort(this.getServerSFTPPort());
clonedAction.setServerRelativePath(this.getServerRelativePath());
clonedAction.setFileName(this.getFileName());
clonedAction.setLocalFilePath(this.getLocalFilePath());
clonedAction.setBasicSettings(this.getBasicSettings());
} catch (InvalidDataException e) {
e.printStackTrace();
LOG.error(e.getMessage());
}
return clonedAction;
}
/**
* {#inheritDoc}
*/
#Override
public void stopExecution() {
// nothing to do
}
/**
* {#inheritDoc}
*/
#Override
public final void shutdown() {
if (this.manager != null) {
this.manager.close();
}
}
public String getServerRelativePath() {
return serverRelativePath;
}
public void setServerRelativePath(String serverRelativePath) {
this.serverRelativePath = serverRelativePath;
}
// Establishing connection
private String createConnectionString(String hostName, String username,
String password, String remoteFilePath) {
return "sftp://" + username + ":" + password + "#" + hostName + "/"
+ remoteFilePath;
}
// Method to setup default SFTP config:
private FileSystemOptions createDefaultOptions() throws FileSystemException {
// Create SFTP options
FileSystemOptions opts = new FileSystemOptions();
// SSH Key checking
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
opts, "no");
// Root directory set to user home
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
// Timeout is count by Milliseconds
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
return opts;
}
}
I have been training myself on Logging. I use log4j library for logging and I am new to design patterns. What I want to ask is how can I create a factory to get a configured logger?
This may be help you.
public class LogFactory {
public static final String TOOLKIT = "logging.toolkit";
public static final String TOOLKITCLASS = "logging.toolkit.class";
public static final String Log4j = "log4j";
public static LogAdapter logAdapter;
public static Object lock = new Object();
/**
* Get specific Log implementation
* #param name
* #return
*/
public static Log getLog(final String name) {
if (logAdapter == null) {
synchronized (lock) {
String toolkitClass = System.getProperty(TOOLKITCLASS);
if (toolkitClass != null) {
System.out.println("\n Logging toolkitClass:" + toolkitClass + "\n\n");
logAdapter = createObject(toolkitClass);
}
else {
String toolkit = System.getProperty(TOOLKIT);
if (toolkit == null) {
toolkit = Log4j;
}
if (toolkit.equalsIgnoreCase(Log4j)) {
logAdapter = new Log4jAdapter();
}
}
//Initialize adapter
logAdapter.init();
}
}
return logAdapter.getLog(name);
}
public static Log getLog(final Class<?> clazz) {
return LogFactory.getLog(clazz.getName());
}
/**
* Create an instance of wrapper class using reflection
* #param className
* #return
*/
private static LogAdapter createObject(final String className) {
Object o = null;
try {
Class<?> cl = Class.forName(className);
Constructor<?> c = cl.getConstructor();
o = c.newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
return (LogAdapter) o;
}
}
I tried to save data to json string in a txt file using Gson and then restore it using Gson either. Things go well if I do it in eclipse. But when packaged to jar, Gson throws Exceptions.
Here is the code for saving the file.
String gsonStr = gson.toJson(masterShips); // masterShips is ArrayList<Ship>
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter("D:\\master_ship.txt"));
writer.write(gsonStr);
} catch (IOException e) {
System.err.println(e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
Then I read the file in eclipse using this code (and it works):
Scanner in = new Scanner(new FileReader("D:\\master_ship.txt"));
String str = in.nextLine();
Log.toDebug(str);
in.close();
JsonParser parser = new JsonParser();
JsonElement je = parser.parse(str);
JsonArray ja = je.getAsJsonArray();
for (int i=0; i<ja.size(); ++i) {
...
}
But after packaged into jar and run in cmd, Exception occurs:
Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.
stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malform
ed JSON at line 1 column 4
at com.google.gson.JsonParser.parse(JsonParser.java:65)
at com.google.gson.JsonParser.parse(JsonParser.java:45)
at kan.util.Master.loadMasterShip(Master.java:44)
at kan.util.Master.load(Master.java:27)
at kan.Main.main(Main.java:22)
Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLeni
ent(true) to accept malformed JSON at line 1 column 4
at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1386)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:531)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:414)
at com.google.gson.JsonParser.parse(JsonParser.java:60)
... 4 more
According to the hint of the Exception, I changed my code and it still works in eclipse:
Scanner in = new Scanner(new FileReader("D:\\master_ship.txt"));
String str = in.nextLine();
in.close();
Reader reader = new StringReader(str);
JsonReader jr = new JsonReader(reader);
jr.setLenient(true);
JsonParser parser = new JsonParser();
JsonElement je = parser.parse(jr);
JsonArray ja = je.getAsJsonArray();
for (int i=0; i<ja.size(); ++i) {
...
}
But jar failed and throws
Exception in thread "main" java.lang.IllegalStateException: This is not a JSON A
rray.
at com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:106)
at kan.util.Master.loadMasterShip(Master.java:58)
at kan.util.Master.load(Master.java:30)
at kan.Main.main(Main.java:22)
As suggested by Sotirios I cut the length of the arraylist down, and when I increase the number of ships to 4, things go wrong. Here is the json:
[{"id":1,"name":"睦月","type":2,"rank":2,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":254,"range":1,"powerups":[1,1,0,0]},{"id":2,"name":"如月","type":2,"rank":1,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":255,"range":1,"powerups":[0,1,0,0]},{"id":6,"name":"長月","type":2,"rank":1,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":258,"range":1,"powerups":[0,1,0,0]},{"id":7,"name":"三日月","type":2,"rank":1,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":260,"range":1,"powerups":[0,1,0,0]}]
↑ colunm 473
Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.
stream.MalformedJsonException: Unterminated object at line 1 column 473
at com.google.gson.internal.Streams.parse(Streams.java:56)
at com.google.gson.JsonParser.parse(JsonParser.java:84)
at kan.util.Master.loadMasterShip(Master.java:55)
at kan.util.Master.load(Master.java:30)
at kan.Main.main(Main.java:22)
Caused by: com.google.gson.stream.MalformedJsonException: Unterminated object at
line 1 column 473
at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:480)
at com.google.gson.stream.JsonReader.hasNext(JsonReader.java:403)
at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:
666)
at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:
659)
at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:
642)
at com.google.gson.internal.Streams.parse(Streams.java:44)
... 4 more
Can anyone help me with this, you will be reaally preciated!
Use this class
import java.util.List;
public class GsonResponse
{
public int id;
public String name;
public int type;
public int rank;
public int fuelMax;
public int bulletMax;
public int slotNum;
public int speed;
public int afterLv;
public int afterId;
public int range;
public List<Integer> powerups;
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the type
*/
public int getType() {
return type;
}
/**
* #param type the type to set
*/
public void setType(int type) {
this.type = type;
}
/**
* #return the rank
*/
public int getRank() {
return rank;
}
/**
* #param rank the rank to set
*/
public void setRank(int rank) {
this.rank = rank;
}
/**
* #return the fuelMax
*/
public int getFuelMax() {
return fuelMax;
}
/**
* #param fuelMax the fuelMax to set
*/
public void setFuelMax(int fuelMax) {
this.fuelMax = fuelMax;
}
/**
* #return the bulletMax
*/
public int getBulletMax() {
return bulletMax;
}
/**
* #param bulletMax the bulletMax to set
*/
public void setBulletMax(int bulletMax) {
this.bulletMax = bulletMax;
}
/**
* #return the slotNum
*/
public int getSlotNum() {
return slotNum;
}
/**
* #param slotNum the slotNum to set
*/
public void setSlotNum(int slotNum) {
this.slotNum = slotNum;
}
/**
* #return the speed
*/
public int getSpeed() {
return speed;
}
/**
* #param speed the speed to set
*/
public void setSpeed(int speed) {
this.speed = speed;
}
/**
* #return the afterLv
*/
public int getAfterLv() {
return afterLv;
}
/**
* #param afterLv the afterLv to set
*/
public void setAfterLv(int afterLv) {
this.afterLv = afterLv;
}
/**
* #return the afterId
*/
public int getAfterId() {
return afterId;
}
/**
* #param afterId the afterId to set
*/
public void setAfterId(int afterId) {
this.afterId = afterId;
}
/**
* #return the range
*/
public int getRange() {
return range;
}
/**
* #param range the range to set
*/
public void setRange(int range) {
this.range = range;
}
/**
* #return the powerups
*/
public List<Integer> getPowerups() {
return powerups;
}
/**
* #param powerups the powerups to set
*/
public void setPowerups(List<Integer> powerups) {
this.powerups = powerups;
}
}
just add below code where u parse
String strJson = "[{\"id\":1,\"name\":\"睦月\",\"type\":2,\"rank\":2,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":254,\"range\":1,\"powerups\":[1,1,0,0]},{\"id\":2,\"name\":\"如月\",\"type\":2,\"rank\":1,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":255,\"range\":1,\"powerups\":[0,1,0,0]},{\"id\":6,\"name\":\"長月\",\"type\":2,\"rank\":1,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":258,\"range\":1,\"powerups\":[0,1,0,0]},{\"id\":7,\"name\":\"三日月\",\"type\":2,\"rank\":1,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":260,\"range\":1,\"powerups\":[0,1,0,0]}]";
GsonResponse gsonResponse = null;
try {
gsonResponse = new Gson().fromJson(strJson,
GsonResponse.class);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
I have been trying to extract the goolge places api photo reference but have not had any success. I was wondering if someone could help me. Below is my code:
// KEY Strings
public static String KEY_REFERENCE = "reference"; // id of the place
public static String KEY_NAME = "name"; // name of the place
public static String KEY_VICINITY = "vicinity"; // Place area name
public static String KEY_PHOTO = "photo_reference";
class LoadPlaces extends AsyncTask<String, String, String> {
/**
* getting google places JSON response
* */
protected String doInBackground(String... args) {
// creating Places class object
googlePlaces = new GooglePlaces();
try {
String types = MenuActivity.type;
String keyword = MenuActivity.keyword;
// get nearest places
nearPlaces = googlePlaces.search(gps.getLatitude(),gps.getLongitude(),
types, keyword);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed Places into LISTVIEW
* */
// Get JSON response status
String status = nearPlaces.status;
// Check for OK status
if (status.equals("OK")) {
// Successfully got places details
if (nearPlaces.results != null) {
// loop through each place
for (Place p : nearPlaces.results) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_REFERENCE, p.reference);
map.put(KEY_NAME, p.name);
map.put(KEY_PHOTO,p.photo);
map.put(KEY_VICINITY, p.vicinity);
// adding HashMap to ArrayList
placesListItems.add(map);
}
// list adapter - removed rating
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, placesListItems,
R.layout.list_item, new String[] {
KEY_REFERENCE, KEY_NAME, KEY_VICINITY, KEY_PHOTO},
new int[] { R.id.reference, R.id.name, R.id.address, R.id.phptp});
// Adding data into ListView
lv.setAdapter(adapter);
}
}
}
Below is my code that performs the search and parses the data:
public class GooglePlaces {
/** Global instance of the HTTP transport. */
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final String LOG_KEY = "GGPlace";
// Google API Key
private static final String API_KEY = "";
// Google Places serach
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?&rankby=distance";
private double _latitude;
private double _longitude;
private double _radius;
private String address;
public PlacesList search(double latitude, double longitude, String types, String keyword)
throws Exception {
this._latitude = latitude;
this._longitude = longitude;
try {
HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
request.getUrl().put("key", API_KEY);
request.getUrl().put("location", _latitude + "," + _longitude);
request.getUrl().put("sensor", "true");
if(types != null)
{
request.getUrl().put("types", types);
request.getUrl().put("keyword", keyword);
}
PlacesList list = request.execute().parseAs(PlacesList.class);
// Check log cat for places response status
Log.d("Places Status", "" + list.status);
return list;
} catch (HttpResponseException e) {
Log.e("Error:", e.getMessage());
return null;
}
}
public static HttpRequestFactory createRequestFactory(
final HttpTransport transport) {
return transport.createRequestFactory(new HttpRequestInitializer() {
public void initialize(HttpRequest request) {
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName("APP NAME");
headers.gdataVersion="2";
request.setHeaders(headers);
JsonHttpParser parser = new JsonHttpParser(new JacksonFactory());
request.addParser(parser);
}
});
}
}
This is my PlaceList class:
public class PlacesList implements Serializable {
#Key
public String status;
#Key
public List<Place> results;
}
Here is my Place class:
public class Place implements Serializable {
#Key
public String id;
#Key
public String name;
#Key
public String reference;
#Key
public String vicinity;
#Key
public Geometry geometry;
#Key
public List<Photo> photos;
}
And finally my Photo class:
public class Photo implements Serializable {
#Key
public String photo_reference;
#Key
public int height;
#Key
public int width;
}
I guess I am calling or passing the photo_reference the wrong way. I am hoping there is someone out there that can help me out. I've been working on this for weeks and have almost completely given up.
Hi firstly your search url is wrong.
You have to follow this format:
https://developers.google.com/places/web-service/photos
Please see below for a complete example:
http://wptrafficanalyzer.in/blog/showing-nearby-places-with-photos-at-any-location-in-google-maps-android-api-v2/
If you download the source code, it will help you see how to fetch the json string in an array which is in another array.
The snippet below just answers the part where you have to fetch the image:
package in.wptrafficanalyzer.locationnearbyplacesphotos;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class PlaceJSONParser {
/** Receives a JSONObject and returns a list */
public Place[] parse(JSONObject jObject){
JSONArray jPlaces = null;
try {
/** Retrieves all the elements in the 'places' array */
jPlaces = jObject.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
}
/** Invoking getPlaces with the array of json object
* where each json object represent a place
*/
return getPlaces(jPlaces);
}
private Place[] getPlaces(JSONArray jPlaces){
int placesCount = jPlaces.length();
Place[] places = new Place[placesCount];
/** Taking each place, parses and adds to list object */
for(int i=0; i<placesCount;i++){
try {
/** Call getPlace with place JSON object to parse the place */
places[i] = getPlace((JSONObject)jPlaces.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
return places;
}
/** Parsing the Place JSON object */
private Place getPlace(JSONObject jPlace){
Place place = new Place();
try {
// Extracting Place name, if available
if(!jPlace.isNull("name")){
place.mPlaceName = jPlace.getString("name");
}
// Extracting Place Vicinity, if available
if(!jPlace.isNull("vicinity")){
place.mVicinity = jPlace.getString("vicinity");
}
if(!jPlace.isNull("photos")){
JSONArray photos = jPlace.getJSONArray("photos");
place.mPhotos = new Photo[photos.length()];
for(int i=0;i<photos.length();i++){
place.mPhotos[i] = new Photo();
place.mPhotos[i].mWidth = ((JSONObject)photos.get(i)).getInt("width");
place.mPhotos[i].mHeight = ((JSONObject)photos.get(i)).getInt("height");
place.mPhotos[i].mPhotoReference = ((JSONObject)photos.get(i)).getString("photo_reference");
JSONArray attributions = ((JSONObject)photos.get(i)).getJSONArray("html_attributions");
place.mPhotos[i].mAttributions = new Attribution[attributions.length()];
for(int j=0;j<attributions.length();j++){
place.mPhotos[i].mAttributions[j] = new Attribution();
place.mPhotos[i].mAttributions[j].mHtmlAttribution = attributions.getString(j);
}
}
}
place.mLat = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
place.mLng = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
} catch (JSONException e) {
e.printStackTrace();
Log.d("EXCEPTION", e.toString());
}
return place;
}
}
I first misunderstood photo_reference as Base64 Encoded String. But it is not indeed it is a reference parameter to identify and fetch a photo from google maps API. Imagine this as a token parameter. So to fetch a photo with max-width 400 you can use below URL.
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=YOUR_API_KEY
For more details visit Google Places documentation
https://developers.google.com/places/web-service/photos
I am using simple-xml to perform XML serialization/deserialization in my Java application. I have a class as follows:
#Root(name="config")
public class Config{
#Element(name="update_interval")
private int updateInterval;
#Element(name="timestamp")
private long timestamp;
//...
//...
}
Now, this would produce XML like the following:
<config>
<update_interval>2000</update_interval>
<timestamp>1234567890</timestamp>
</config>
Question:
How can I override the element name at runtime, so that in some cases, the XML reads as follows?
<config>
<updt_int>2000</updt_int>
<ts>1234567890</ts>
</config>
Edit:
To clarify, I want to override the element names only in some cases. So basically,
if(condition){
//Override Element Names
} else {
//Serialize Normally
}
I found an easy way to achieve serialization in this case, thanks to this comment.
However, I haven't been able to de-serialize such an XML document. Here's my partial solution:
/*
* Config.java
*/
#Root(name="config", strict = false)
public class Config {
#Element(name="timestamp", required = false)
private long timestamp;
#Element(name = "update_interval", required = false)
private int updateInterval;
public Config() {
}
public int getUpdateInterval() {
return updateInterval;
}
public void setUpdateInterval(int updateInterval) {
this.updateInterval = updateInterval;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
#Override
public String toString() {
return "Config{" +
"timestamp=" + timestamp +
", updateInterval=" + updateInterval +
'}';
}
}
/*
* Custom Visitor implementation
*/
public class MyInterceptor implements Visitor {
private static int sReadCount = 0;
private static int sWriteCount = 0;
#Override
public void read(Type field, NodeMap<InputNode> node) throws Exception {
/*
* This is where I need help!
*
*
* This method is only called once: for the <config> node
* It is not called for the other nodes since they are not "recognized"
* i.e., there are no annotations for the nodes <ts> and <updt_int>
*/
System.out.println("Read Count : "+ (++sReadCount));
System.out.println(node.getName());
System.out.println(node.getNode());
}
#Override
public void write(Type field, NodeMap<OutputNode> node) throws Exception {
/*
* This works like a charm.
*/
System.out.println("Write Count : "+ (++sWriteCount));
OutputNode opNode = node.getNode();
if("timestamp".equals(opNode.getName())){
opNode.setName("ts");
}
if("update_interval".equals(opNode.getName())){
opNode.setName("updt_int");
}
}
}
/*
*
*/ Main class
public class Bootstrap {
static final Random RANDOM = new Random();
public static void main(String [] args){
Config cfg = new Config();
cfg.setTimestamp(RANDOM.nextLong());
cfg.setUpdateInterval(1000);
Serializer serializer = new Persister(new VisitorStrategy(new MyInterceptor()));
StringWriter writer = new StringWriter();
try {
serializer.write(cfg, writer);
} catch (Exception e) {
e.printStackTrace();
}
String serialized = writer.toString();
System.out.println(serialized);
Config desCfg = null;
try {
desCfg = serializer.read(Config.class, serialized);
} catch (Exception e) {
e.printStackTrace();
}
if(desCfg != null){
System.out.println(desCfg.toString());
}
}
}