I am trying to add functionality to an existing JAVA Spring/Angular JS web application that uses REST calls along with JPA/Hibernate/Liquibase. I have followed what is there and while I have worked through a lot of errors I cannot figure out what is hopefully the last error. The application loads but there is no data returned to display. And I know the data is in the database as a direct SQL query pulls it back. So it has to be with the Spring/JPA/Hibernate setup. I see in the logs that the Angular controller calls my PropertiesRestController.java file and uses the correct method. That in turn calls the correct method in my PropertiesDataService.java file which uses the correct query/method in my Repository.java file. But when I debug the point of breakdown the code appears to breakdown in the AngularJS service on the line "data = angular.fromJson(data);". The logs show the correct parameters for each method but then error out on the PropertiesRestController.java method call with ". . . logging.LoggingAspect - Illegal Argument ['Sold','30,'jwt.model.UserContext#xzyABC123',Page request[number: 0, size 20, sort: null]] in . . . . web.rest.controller.PropertiesRestController.findMyProperties() . . . logging.LoggingAspect - Exception in . . . web.rest.controller.PropertiesRestController.findMyProperties() with cause = null". Also, on the front end in the browser with developer tools I get "SyntaxError" at the "findMyProperties.transformResponse line of my AngularJS service for this page view.
I have done extensive web research on this. And I have added for example "return Optional.ofNullable(myProperty).map(a -> new ResponseEntity<>(a, HttpStatus.OK)).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND) to the PropertiesRestController.java method call. Before I jsut tried to return Page myProperty = myPropertyDataService.getMyProperties( . . . . ). Others had issues with null being returned and needed to handle it. I am getting data for sure (if the SQL is correct) but in case the query needed adjusting I decided to at least handle the null that is reported in the log file. I've made sure my SQL in #Query is referencing entity names not tables/SQL language (although honestly some of the ones already used I don't see in the entity definitions so I don't know where they got those to use from.)
AngularJS Controller
$scope.myPropertiesP = [];
$scope.loadall = function(){
MyProperties.findMyProperties({propertyStatus:"Pending",listingDate:0,function(result){
$scope.myPropertiesP = result.content;
});
$scope.loadall();
AngularJS Service
use strict;
angular.module('propertyApp')
.factory('MyProperties',function($resource){
return $resource('rest/api/Properties/my/:propertyStatusName/:propertyListingDate', {}, {
'findMyProperties': method: 'GET',
transformResponse: function(data){
data = angular.fromJson(data);
return data;
});
});
});
PropertyRestController.java
#GetMapping(value='/properties/my/{propertyStatusName}/{propertyListingDate}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Page<Properties>> findMyProperties(#PathVariable propertyStatusName, #PathVariable Integer propertyListingDate, #Authenticated User user, Pageable page){
Page<Properties> myProperty = myPropertyDataService.getMyProperties(propertyStatusName, propertyListingDate,user.getUser(),pageable);
return Optional.ofNullable(myProperty).map(a -> new ResponseEntity<>(a, HttpStatus.OK)).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
PropertyDataServices.java
public Page<Properties> getMyProperties(String propertyStatusName, Integer propertyListingDate, User user, Pageable page){
if(pageable != null){
if(propertyListingDate==0)&&(propertyStatusName=='Pending'){
return PropertyRespository.MyPropertiesP(user.getId(),pageable);
} else {
return PropertyRespository.MyPropertiesP(user.getId(), newPageRequest(0,20));
}
}
PropertyRepository.java
public interface PropertyRespository extends JpaRepsotiory(Property,Long>{
Page<Property> findByNameContaingIgnoreCase(String name, Pageable pageable);
. . .
#Query("select prop from Property prop where prop.propertyOwner = :propertyOwnerId AND (propertyStatus=3 OR prop.propertyStatus=2) ORDER BY prop.propertListingDate DESC")
Page<Property> myPropertiesP(#Param("propertyOwner") Integer propertyOwnerId, Pageable pageable):
}
I am supposed to get back JSON strings of database objects to display through AngularJS.
Related
So I have in my code POST method :
#POST
#Path("/send/{userPost}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public Response sendUser(#PathParam("userPost") String userPost ) {
List<Post>userPosts = new ArrayList();
Post post = new Post(99,userPost,"Bartek Szlapa");
userPosts.add(post);
User user = new User(99,"Bartek","Szlapa",userPosts);
String output = user.toString();
return Response.status(200).entity(output).build();
}
unfortunately its not working. I'm getting 404 error. Server is configured correctly because other methods work perfectly. Funny thing is that when I remove {userPost} , parameter : #PathParam("userPost") String userPost and send empty request : http://localhost:8080/JavaAPI/rest/api/send it works - I'm getting new User object with null at some fields. Do you know why I cannot send parameter ? Thanks in advance for help! :)
What you are sending is not a path parameter to send your value as a path parameter based on your api , let us say you are trying to send "test"
http://localhost:8080/JavaAPI/rest/api/send/test
if you want to use query params
#POST
#Path("/send")
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public Response sendUser(#QueryParam("userPost") String userPost ) {
and your request should be
http://localhost:8080/JavaAPI/rest/api/send?userPost=test
Your "userPost" parameter is not in the Path : localhost:8080/JavaAPI/rest/api/send?=test
You defined this path :
#Path("/send/{userPost}")
So, your URI should be :
localhost:8080/JavaAPI/rest/api/send/test
{"error":"OK","langId":1,
"langName":"C++",
"langVersion":"5.1.1",
"time":0,
"date":"2017-04-03 15:38:19",
"status":0,
"result":11,
"memory":0,
"signal":0,"public":false,
"source":"","output_encoded":"",
"output_type":"text","output":"",
"stderr":"",
"cmpinfo":"\/usr\/lib\/gcc\/x86_64-linux-gnu\/6\/..\/..\/..\/x86_64-linux-gnu\/Scrt1.o: In function `_start':\n(.text+0x20): undefined reference to `main'\ncollect2: error: ld returned 1 exit status\n"
}
I am getting an error, I am unable to figure out where I am going wrong?
API Call :
public interface SubmitCodeService {
#Headers("Content-Type: application/json")
#POST("/api/v3/submissions")
Call<IdResponse> postCode(#Body JSONObject code, #Query("access_token") String accessToken );
#GET("/api/v3/submissions/{id}")
Call<CodeOutputResponse> getOutput(
#Path("id") Integer submissionId,
#Query("access_token") String accessToken,
#Query("withOutput") boolean withOutput,
#Query("withSource") boolean withSource,
#Query("withStderr") boolean withStderr,
#Query("withCmpinfo") boolean withCmpinfo);
}
I am submitting a simple HelloWorld program, I am getting an id back in response, however when I try to get the output, it throws this error.
Thanks in advance for your help.
Update : I am able to get it up and running by modifying the code to this :
Call<IdResponse> postCode(#Body HashMap<String,String> code, #Query("access_token") String accessToken );
"source":""
It seems that your postCode function is not correctly sending the source code. This means no main function is defined which causes the error mentioned in your post.
You need to review how you construct the value passed to code in postCode to see if it matches what the API expects.
I am trying to pull about 20,000 users from my Google domain. However, i know that Google only has a limit of about 500 users for a pull request. I know about the pageToken stuff, but the documentation for it online is terrible. Can someone show me how to use the pageToken? Please keep in mind i am using the google client libraries. This is what my code looks like so far:
#Test
public void paginationTest() throws IOException, NullPointerException, GeneralSecurityException {
try {
Directory directory = GCAuthentication.getDirectoryService("xxx", "vvv", dddd);
Directory.Users.List list = directory.users().list().setOrderBy("email").setMaxResults(500).setDomain("dev.royallepage.ca");
do {
com.google.api.services.admin.directory.model.Users users = list.execute();
java.util.List<User> uL = users.getUsers();
//uL.addAll(users.getUsers());
//list.setPageToken(list.getPageToken());
System.out.println(uL.size());
}while (list.getPageToken() != null && list.getPageToken().length() > 0);
}catch(NullPointerException e) {
}
}
Please advise what i am doing wrong! Thanks,
Mesam
You will have to create a function that will get the pageToken variable then call another request including the nextPageToken.
Use the pageToken query string for responses with large number of groups. In the case of pagination, the response returns the nextPageToken property which gives a token for the next page of response results. Your next request uses this token as the pageToken query string value.
Sample Code Request:
GET https://www.googleapis.com/admin/directory/v1/users
?domain=primary domain name&pageToken=token for next results page
&maxResults=max number of results per page
&orderBy=email, givenName, or familyName
&sortOrder=ascending or descending
&query=email, givenName, or familyName:the query's value*
Hope this helps!
iam trying to orderlookup droplet API by passing some parameters.I assume that the parameters which are mandatory is userId and organisationIds which i have passed and additionally i have also passed "state" parameter.All these params are passed thru request and then the service method of droplet is invoked.But the service method returns nothing.My goal is to check whether this droplet this retrieving the expected set of orders or not.We can use droplet invoker but i tried that way but it didnt work may be i missed something.Please help me out!!
this is my code when i tried to use OrderLookUp API
DynamoHttpServletRequest request = ServletUtil.getCurrentRequest();
mTestService.setCurrentRequest(request);
if (request == null) {
mTestService.vlogError("Request is null.");
Assert.fail("Request is null ");
}
else
{
Object droplet = mTestService
.getRequestScopedComponent("OrderLookupDroplet");
OrderLookupDroplet=(OrderLookup) droplet;
request.setParameter("state", "submitted");
request.setParameter("organisationIds", organizationIds);
request.setParameter("userId", userId);
ByteBuffer buffer = ByteBuffer.allocate(1024);
DynamoHttpServletRequest dynRequest = (DynamoHttpServletRequest) request;
TestingDynamoHttpServletRequest wrappedRequest = new TestingDynamoHttpServletRequest(
dynRequest, buffer);
TestingDynamoHttpServletResponse wrappedResponce = new TestingDynamoHttpServletResponse(
dynRequest.getResponse());
OrderLookupDroplet.service(wrappedRequest, wrappedResponce);
}
the above sample is only part of the code..
this is the code when i tried using droplet invoker
DropletInvoker invoker = new DropletInvoker(mNucleus);
invoker.getRequest().setParameter("state", "submitted");
// String [] siteIds = {"siteA", "siteB"};
// invoker.getRequest().setParameter("siteIds", Arrays.asList(siteIds));
String [] organizationIds = {"OrgA", "OrgB"};
invoker.getRequest().setParameter("organizationIds", organizationIds);
String [] orderIds = {"orderautouser001OrgA" , "orderautouser001OrgB"};
invokeDroplet(invoker, "autouser001", orderIds);
......
protected void invokeDroplet(DropletInvoker pInvoker, String pUserId, String[] pOrderIds) throws Exception
{
Map<String, Object> localParams = new HashMap();
localParams.put("userId", pUserId);
DropletResult result = pInvoker.invokeDroplet("/atg/commerce/order/OrderLookup", localParams);
RenderedOutputParameter oparam = result.getRenderedOutputParameter("output", 0);
assertNotNull("'output' oparam was not rendered", oparam);
assertEquals("Check totalCount.", pOrderIds.length, oparam.getFrameParameter("totalCount"));
List<Order> orders = (List<Order>)oparam.getFrameParameter("result");
assertEquals("Check order array length.", pOrderIds.length, orders.size());
for (int index = 0; index < pOrderIds.length; index++) {
boolean found = false;
for (Order order: orders) {
if (pOrderIds[index].equals(order.getId())) {
found = true;
break;
}
}
assertTrue("Expected orderId " + pOrderIds[index] + " not found in result array", found);
}
in first case i donno how to retrieve the orders by directly using orderlookup api....and in second case though i know how to use it ,iam still failing!! please help me out..thanks in advance
You should't use droplets in java classes they should be used only inside jsp pages. Documentation of OrderLookup with example hot to use it on jsp page is here.
If you want to get orders or any other data stored in a repository you should use repository API with RQL (Repository Query Language). Example how to get data from repository you can find here and RQL grammar here.
Thanks for giving your opinions.Good news is we can invoke droplets from any other API
OrderLookup droplet = (OrderLookup) sNucleus.resolveName("/atg/commerce/order/OrderLookup");
ServletTestUtils utils = new ServletTestUtils();
mRequest = utils.createDynamoHttpServletRequestForSession(sNucleus, null, null);
ServletUtil.setCurrentRequest(mRequest);
mResponse = new DynamoHttpServletResponse();
mRequest.setResponse(mResponse);
mResponse.setRequest(mRequest);
mResponse.setResponse(new GenericHttpServletResponse());
mRequest.setParameter("userId", "publishing");
droplet.setSearchByUserId(true);
droplet.service(mRequest, mResponse);
ArrayList<Order> orders = (ArrayList<Order>) mRequest.getObjectParameter("result");
here the "result" param is output param which this droplet sets.and the userId i have hardcoded as "publishing" which i have created.Ignore servletTestUtils class that is created by me which has not much to do with droplet theory here :)
I assume from your code example, and the fact that you mention DropletInvoker that you are writing a unit test, and that this is not functional code.
If it is functional code, you really, really, should not invoke a droplet from another Nucleus component. A droplet exists solely to be used in a JSP page. If you need the functionality of the droplet in Java code, you should refactor the droplet into a service that holds the main logic, and a droplet that simply acts as a façade to the service to allow it to be invoked from a page.
In the case of the OrderLookup look droplet, you don't need to refactor anything. The service to use should be OrderManager or OrderTools depending on what you need. Note, there is a difference between Order objects and Order repository items, and you should prefer to use order objects - so only use the Order Repository directly if you really need to.
I have an Android Application that is stored in the Cloud, with Google App Engine. I use Cloud Endpoints. My problem is that I cannot send the data from the server to my client(Android Device), or better said, so far, I have no idea how to do that.
So far, I have managed to insert data in the datastore, by creating an endpoint and calling the method that is in charge with adding a record in the database(that's located on the server side, in myProject - AppEngine) , using the following code (on the client):\
Noteendpoint.Builder endpointBuilder = new Noteendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) { }
});
Noteendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
try {
// Construct the note.
Note note = new Note().setDescription("Note DescriptionRoxana");
String noteID = new Date().toString();
note.setId(noteID);
note.setEmailAddress("E-Mail AddressRoxana");
// Insert the Note, by calling a method that's on the server side - insertNote();
Note result = endpoint.insertNote(note).execute();
} catch (IOException e) {
e.printStackTrace();
}
But I cannot see a way of retrieving data from the datastore and to display it on the server side. I tried to do the same, create an endpoint, that will call the method that retrieves all the records in the database (method that is located on the server), but my application crashes.
The code for the method that retrieves data from the datastore is the following:
public CollectionResponse<Note> listNote(
#Nullable #Named("cursor") String cursorString,
#Nullable #Named("limit") Integer limit) {
EntityManager mgr = null;
Cursor cursor = null;
List<Note> execute = null;
try {
mgr = getEntityManager();
Query query = mgr.createQuery("select from Note as Note");
if (cursorString != null && cursorString != "") {
cursor = Cursor.fromWebSafeString(cursorString);
query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
}
if (limit != null) {
query.setFirstResult(0);
query.setMaxResults(limit);
}
execute = (List<Note>) query.getResultList();
cursor = JPACursorHelper.getCursor(execute);
if (cursor != null)
cursorString = cursor.toWebSafeString();
// Tight loop for fetching all entities from datastore and accomodate
// for lazy fetch.
for (Note obj : execute)
;
} finally {
mgr.close();
}
return CollectionResponse.<Note> builder().setItems(execute)
.setNextPageToken(cursorString).build();
}
You see, the returned type is collection response. You have access to this type of data, after performing the following import:
import com.google.api.server.spi.response.CollectionResponse;
I inferred that this is a data type characteristic to the server side, thus, I have no idea how I can cast it into a List, ArrayList, or any other type of collection, that can be used on the client side.
How should I do it then? Since adding data was so easy and so straight forward, I have assumed that retrieving data would be performed in the same manner, but apparently I am missing something essential for this matter.
Thank you in advance!
The classes you use in the backend are not the same as the classes you'll use in the client. Endpoints will generate a set of libraries for you, either on the command line or with tooling like Google Plugin for Eclipse. See Using Endpoints in an Android Client.
The generated class representing the collection of Notes in your example will be named something like NotesCollection. This object will have a method getItems, which provides you a List<Note> you can iterate on in your Android application.
Similar to having an endpoint for inserting data into a datastore model(methods of type POST), you need to have an endpoint for querying the data from the datastore model (methods of type GET). After you define both these methods, you need generate your discovery document and client library so that clients know about both these methods and can call them. If your speaking about displaying the data in the web itself then you can build a Javascript client by using the required client library.