How can i return List of json object like {"items":"["{"":""},{"":""},..."]"} form Spring MVC3.0? Please some one help on this...
#RequestMapping(value="/list", method=RequestMethod.GET)//, headers=ACCEPT_JSON)
#ResponseBody
public List<User> userList() {
LOG.info("get list of Users");
List<User> users = new ArrayList<User>();
users.add(new User("user1", "pass1", "name1", Boolean.TRUE));
users.add(new User("user2", "pass2", "name2", Boolean.TRUE));
users.add(new User("user3", "pass3", "name3", Boolean.TRUE));
return users;
}
Related
Is it possible to use a foreach loop in a BLC to iterate through the fields of a PXResultSet to get the FieldNames?
Is this doable? I can't seem to find a good way.
Thanks...
The PXResultset records are selected from a view. You can get the field names from the View.
Here's a full example:
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
public override void Initialize()
{
// Get field list from data view
var dataView = new PXSelect<SOOrder>(Base);
string fieldNames = string.Join(",", GetFieldNames(dataView.View, Base.Caches));
// You don't need result set to get field names
PXResultset<SOOrder> resultSet = dataView.Select();
throw new PXException(fieldNames);
}
public string[] GetFieldNames(PXView view, PXCacheCollection caches)
{
var list = new List<string>();
var set = new HashSet<string>();
foreach (Type t in view.GetItemTypes())
{
if (list.Count == 0)
{
list.AddRange(caches[t].Fields);
set.AddRange(list);
}
else
{
foreach (string field in caches[t].Fields)
{
string s = String.Format("{0}__{1}", t.Name, field);
if (set.Add(s))
{
list.Add(s);
}
}
}
}
return list.ToArray();
}
}
When run, this example will show the fields names used in the data view in Sales Order screen SO301000 as an exception.
Field names are contained in Cache object. If you really need to get field names from PXResultset you need to iterate the cache types in the result set.
Example for first DacType (0) of result set:
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
public override void Initialize()
{
var dataView = new PXSelect<SOOrder>(Base);
PXResultset<SOOrder> resultSet = dataView.Select();
foreach (PXResult result in resultSet)
{
Type dacType = result.GetItemType(0);
foreach (var field in Base.Caches[dacType].Fields)
PXTrace.WriteInformation(field);
}
}
}
I have an API with 2 different response:
response OK
{ "name": "test" }
response KO
[
{
"name_1": "test",
"name_2": "test"
}
]
the problem is that using Retrofit, normally, I use a model to parse results but response KO has not an array name.
How can I create a model? (I cannot change the API)
So to add another POJO you can do this:
private static Gson gson = new GsonBuilder()
.registerTypeAdapter(Model1.class, new GsonDeserializer<Model1>())
.registerTypeAdapter(Model2.class, new GsonDeserializer<Model2>())
//or create a POJO for the names array of Model2
.registerTypeAdapter(Model2.class, new GsonDeserializer<Names>())
Where GsonDeserializer is a custom serializer that can be defined, like:
public class GsonDeserializer<T> implements JsonDeserializer<T> {
#Override
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject el = json.getAsJsonObject();
return new Gson().fromJson(el, typeOfT);
}
And then in your Retrofit client you just add:
retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
I am a newbee to Couch and I found lazy-fetching interesting. So I was trying that out but probably due to something wrong I did, it doesn't work and I can't figure out what is wrong. I referred http://ektorp.org/reference_documentation.html#d100e394. I get the error below. (I am able to read the docs separately but not by document referencing). Any help would be much appreciated. I'm using ektorp version 1.4.1.
09:51:03.581 [main] DEBUG org.ektorp.impl.StdCouchDbConnector - Querying CouchDb view at /employee/_design/Employee/_view/ektorp_docrefs_addresses?startkey=%5B%22222%22%2C%22addresses%22%5D&endkey=%5B%22222%22%2C%22addresses%22%2C%7B%7D%5D&include_docs=true.
Exception in thread "main" org.ektorp.DocumentNotFoundException: nothing found on db path: /employee/_design/Employee/_view/ektorp_docrefs_addresses?startkey=%5B%22222%22%2C%22addresses%22%5D&endkey=%5B%22222%22%2C%22addresses%22%2C%7B%7D%5D&include_docs=true, Response body: {"error":"not_found","reason":"missing"}
at org.ektorp.http.StdResponseHandler.createDbAccessException(StdResponseHandler.java:40)
at org.ektorp.http.StdResponseHandler.error(StdResponseHandler.java:68)
at org.ektorp.http.RestTemplate.handleResponse(RestTemplate.java:110)
at org.ektorp.http.RestTemplate.getUncached(RestTemplate.java:27)
at org.ektorp.impl.StdCouchDbConnector.executeQuery(StdCouchDbConnector.java:431)
at org.ektorp.impl.StdCouchDbConnector.queryView(StdCouchDbConnector.java:423)
at org.ektorp.impl.docref.ViewBasedCollection.loadSetResult(ViewBasedCollection.java:69)
at org.ektorp.impl.docref.ViewBasedCollection.loadFromBackReferences(ViewBasedCollection.java:50)
at org.ektorp.impl.docref.ViewBasedCollection.initialize(ViewBasedCollection.java:102)
at
org.ektorp.impl.docref.LazyLoadingViewBasedCollection.invoke(LazyLoadingViewBasedCollection.java:27)
at com.sun.proxy.$Proxy13.size(Unknown Source)
at com.poc.main.Main.main(Main.java:37)
My test files are below.
Employee doc
{
"_id": "222",
"_rev": "1-32d4d52d4ea11b521b1e366959ce5557",
"name": "Mariamma",
"age": 21
}
Address doc
{
"_id": "ad1",
"_rev": "2-39f3162e0fc63ed5526adda5ae496291",
"employeeId": 222,
"addressLine1": "555 Randolph",
"city": "Chicago"
}
Employee.java
public class Employee extends CouchDbDocument {
private String name;
private int age;
#DocumentReferences(backReference = "employeeId", fetch = FetchType.LAZY, cascade=CascadeType.NONE)
private Set<Address> addresses = new HashSet<Address>();
// getters and setters
}
Address.java
public class Address extends CouchDbDocument {
private String employeeId;
private String addressLine1;
private String addressLine2;
private String city;
private String State;
private String zipCode;
// getters and setters
}
EmployeeDao.java
public class EmployeeDao {
private final CouchDbConnector db;
public EmployeeDao() {
db = getEmployeeDatabaseConnector();
}
public CouchDbConnector getEmployeeDatabaseConnector() {
HttpClient httpClient = new StdHttpClient.Builder().build();
CouchDbInstance couchDbInstance = new StdCouchDbInstance(httpClient);
CouchDbConnector connector = new StdCouchDbConnector("employee", couchDbInstance);
connector.createDatabaseIfNotExists();
return connector;
}
public Employee read(String employeeId) {
return this.db.get(Employee.class, employeeId);
}
}
Main.java
public class Main {
public static void main(String[] args) {
EmployeeDao dao = new EmployeeDao();
Employee employee = dao.read("222");
System.out.println(employee.getName());
System.out.println(employee.getAddresses().size()); // this line throws error.
}
}
From your stack trace
... Response body: {"error":"not_found","reason":"missing"}
This suggests that the view /_design/Employee/_view/ektorp_docrefs_addresses isn't there.
Update
Chapter 6 of the Ektorp Reference Docs talks about view generation. It looks like you are not created it yourself and have not told Ektorp to do it for you.
You should look at creating a repository class for Employee by extending CouchDbRepositorySupport and then calling initStandardDesignDocument() on it.
I am working on my first Notes/XPages/Java application and I am stuck at some of the basic 'crud' level. The following is part of the managed bean. I can load the data on to the XPage, but saving the Checkbox field is causing me problems, i.e. it won't save. I assume it is to do with the data type as the CheckboxGroup is multivalued.
Form Fields are:
Category
Employment Role
Variables
public class TrainingModule implements Serializable {
private String Category;
private Object EmploymentRole;
public String getCategory() {
return Category; }
public void setCategory(final String category) {
Category = category;}
public Object getEmploymentRole() {
return EmploymentRole;}
public void setEmploymentRole(final Object employmentRole) {
EmploymentRole = employmentRole;}
Load Method
public void load(final String unid) {
setUnid(unid);
Document doc = null;
try {
doc = ExtLibUtil.getCurrentDatabase().getDocumentByUNID(getUnid());
setCategory(doc.getItemValueString("Category"));
setEmploymentRole(doc.getItemValue("EmploymentRole"));
etc
Save Method
public boolean saveData() {
boolean result = false;
Document doc = null;
try {
doc.replaceItemValue("Category", Category);
doc.replaceItemValue("EmploymentRole", EmploymentRole);
result = doc.save()
etc
XPage
<xp:checkBoxGroup id="checkBoxGroup1"
value="#{TrainingModule.employmentRole}">
<xp:selectItem itemLabel="Admin" itemValue="Admin">
</xp:selectItem>
<xp:selectItem itemLabel="Installation" itemValue="Installation">
</xp:selectItem>
<xp:selectItem itemLabel="Proj Man" itemValue="Proj Man">
</xp:selectItem>
</xp:checkBoxGroup>
I know there are similar postings, but I just can't seem to relate them to what I am trying to achieve.
My next task will be using upload and download controls with Java so any hints or traps to avoid would be great.
Any help would be appreciated.
Define your employment roles as a field of type ArrayList<String>:
private List<String> employmentRoles = new ArrayList<String>();
public void setEmploymentRoles(List<String> employmentRoles) {
this.employmentRoles = employmentRoles;
}
public List<String> getEmploymentRoles() {
return employmentRoles;
}
Read the values with
setEmploymentRoles(doc.getItemValue("EmploymentRole"));
and save the values with
doc.replaceItemValue("EmploymentRole", new Vector(getEmploymentRoles()));
Btw, you shouldn't start a field name with a capital letter. Look here for Java naming conventions.
Since you need to load/save your data, you might be better off with an object data source. Anyway try this:
public Object[] getEmploymentRole() {
return EmploymentRole;}
public void setEmploymentRole(final Object[] employmentRole) {
EmploymentRole = employmentRole;}
An array can't be cast to an Object and a checkboxgroup tries to get/set an array.
This then leads to a slight change in your save method:
doc.replaceItemValue("Category", Category);
Vector v = new Vector(Arrays.asList(EmploymentRole));
doc.replaceItemValue("EmploymentRole", v);
Let us know how it goes
I have been asked to retrieve the contents of a document library and display them on a webpage with links to download using MVC. I can retrieve all the documents from the library with no issue. However when the documents are stored within subfolders in my document library my links only open the folder.
My document library structure is
Document Library
Document 1
Document 2
Document 3
Folder 1
Document 4
Folder 2
Document 5
I need to be able to get the child documents from within the folders and not just the documents within the document library.
Here is my code:
namespace SharePointMVC.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
DefaultModel model = new DefaultModel();
List<DocumentModel> documents = new List<DocumentModel>();
List<FolderModel> folders = new List<FolderModel>();
List<object> itemModels = new List<object>();
using (ClientContext context = new ClientContext("MYSPSITE"))
{
List list = context.Web.Lists.GetByTitle("MYDOCUMENTLIBRARY");
context.Load(list);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection listitems = list.GetItems(query);
context.Load(list);
context.Load(listitems);
context.ExecuteQuery();
foreach (ListItem listItem in listitems)
{
IEnumerable<object> items = ProcessListItems(listItem);
itemModels.AddRange(items);
}
model.Documents = documents;
}
return View(model);
}
public IEnumerable<object> ProcessListItems(ListItem listItem)
{
List<object> items = new List<object>();
if (listItem.FileSystemObjectType == FileSystemObjectType.Folder)
{
FolderModel FolderModel = new FolderModel();
foreach (ListItem childListItem in listItem.childItems)
{
IEnumerable<object> childItems = ProcessListItems(childListItem);
}
items.Add(FolderModel);
}
else
{
DocumentModel documentModel = new DocumentModel();
items.Add(documentModel);
}
}
public ActionResult About()
{
return View();
}
}
}
Any help will be greatly appreciated!
Try changing query.ViewXml = "<View/>"; to query.ViewXml = "<View Scope=\"Recursive\"/>";
This tell SharePoint to return items from all folders. If you want folder information returned as well, change Recursive to RecursiveAll.