New to Jersey(REST Framework for Java) and I'm trying to setup two resources, in two separate classes that share a root path, and I'm having a problem.
So, I have something like:
#Path("/users")
public class User extends RestSupport {
#GET
#Path("/{user_uuid}")
public String get(#PathParam("user_uuid") String uuid) {
return "Hello User " + uuid;
}
}
The above class works. However, I want to create a child resource in a separate class. But when I do this, it seems to create a URI naming conflict. So, here, I want to get all the pets for a particular users
#Path("/users")
public class Pets extends RestSupport {
#GET
#Path("/{user_uuid}/pets")
public String get(#PathParam("user_uuid") String uuid) {
return "Hello Pets " + uuid;
}
}
These top-level resources have lots of child resources, so I'm looking for the best way to organize them. Any help would be appreciated.
Change the path of Pets class from #Path("/users")to#Path("/users/{user_uuid}/pets")
Don't add the HTTP annotation #GET on your Users root resource method if you want Jersey to delegate calls to a child resource. Consider a User class:
public class User {
String uuid;
User(String id) { this.uuid = id; }
#GET
public String get() { return "Hello user " + uuid; }
#GET
#Path("/pets")
public String getPets() { return "Hello pets " + uuid; }
}
and then adjust your Users resource:
#Path("/users")
public class Users {
#Path("/{user_uuid}")
public User get(#PathParam("user_uuid") String uuid) {
// Get the user from the DAO here...
return new User(uuid);
}
}
Related
I am trying to make a RESTful application in Java using Spring boot by following the tutorial here. I want to modify it so that I can extract an identifier from the URL and use it to serve requests.
So http://localhost:8080/members/<memberId> should serve me a JSON object with information about the member whose ID is <memberId>. I don't know how to
Map all http://localhost:8080/members/* to a single controller.
Extract the from the URL.
Should the logic of extracting the memberId and using it be part of the controller or a separate class, as per the MVC architecture?
I am new to Spring/Spring-boot/MVC. It is quite confusing to get started with. So please bear with my newbie questions.
Map all http://localhost:8080/members/* to a single controller.
You can use a placeholder in a request mapping to so it'll handle multiple URLs. For example:
#RequestMapping("/members/{id}")
Extract the id from the URL
You can have the value of a placeholder injected into your controller method using the #PathVariable annotation with a value that matches the name of the placeholder, "id" in this case:
#RequestMapping("/members/{id}")
public Member getMember(#PathVariable("id") long id) {
// Look up and return the member with the matching id
}
Should the logic of extracting the memberId and using it be part of the controller or a separate class, as per the MVC architecture?
You should let Spring MVC extract the member id from the URL as shown above. As for using it, you'll probably pass the URL to some sort of repository or service class that offers a findById method.
As you can see in the code below, service for customer are in one controller to get one and to add new customer.
So, you will have 2 services:
http://localhost:8080/customer/
http://localhost:8080/customer/{id}
#RestController("customer")
public class SampleController {
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Customer greetings(#PathVariable("id") Long id) {
Customer customer = new Customer();
customer.setName("Eddu");
customer.setLastname("Melendez");
return customer;
}
#RequestMapping(value = "/{id}", method = RequestMethod.POST)
public void add(#RequestBody Customer customer) {
}
class Customer implements Serializable {
private String name;
private String lastname;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getLastname() {
return lastname;
}
}
}
I am having two namespaces with two classes with same Name something like this "public partial class CustomerDetail" one from "namespace MS.Client" which implements "IClient" Interface and another one from "namespace MS.Customer" which implements "ICustomerInfo" Interface both in different assembly as well. am trying to access "CustomerDetail" from some other "namespace MS.Applications.View" which has a reference for "namespace MS.Client" but when I suppose to instantiate the "CustomerDetail" class in "namespace MS.Applications.View" I would except all the properties that belongs to "CustomerDetail" in all the namespaces correct? but it was not actually working. can any one help me out from this?
namespace MS.Client
{
public partial class CustomerDetail : IClient
{
private string name;
public string CustName
{
get { return name; }
set { name = value; }
}
private string address;
public string CustAddress
{
get { return address; }
set { address = value; }
}
}
}
namespace MS.Customer
{
public partial class CustomerDetail : ICustomerInfo
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string address;
public string Address
{
get { return address; }
set { address = value; }
}
}
}
please let me know if any one cant understand my summary.
No, classes are local to their namespaces and thus, you can not modify a class from a different namespace. All classes have a fully qualified name, which is their real name, and the namespace is part of it.
What you are actually doing in your code is defining two different CustomerDetail classes, each in a different namespace, effectively being: MS.Customer.CustomerDetail and MS.Client.CustomerDetail.
In order to achieve what you are trying, you need to change to change one of the namespaces so they actually match and the CustomerDetail are actually the same (i.e. they have the same fully qualified name since they are prefixed by the same namespace and have the same name).
I tried working on it. But,not able to figure out the issue since I'm quite new to this. I have attached several screenshots to see the issue I'm facing right now.
#Path("/emp")
public class EmployeeService {
#GET
#Path("/emp/{empID}")
#Produces(MediaType.APPLICATION_XML)
public Employee getEmployee(#PathParam(value = "empID") String empID) {
Employee employee = new Employee();
employee.setEmailId(empID);
employee.setName("Rony John");
employee.setEmailId("rony.java#gmail.com");
return employee;
}
#POST
#Path("/create")
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public Employee createEmployee(Employee employee) {
// Create logic
return employee;
}
#POST
#Path("/update")
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public Employee updateEmployee(Employee employee) {
employee.setName(employee.getName() + " updated");
return employee;
}
#DELETE
#Path("/delete/{empID}")
public Response deleteEmployee(#PathParam(value = "empID") String empID) {
return Response.status(200)
.entity("Employee with " + empID + " is deleted successfully.")
.build();
}
}
The lack of providers is not relevant, it just means you don't have any.
You have an index.jsp, but if you mapped the Jersey filter at the context root (/), it's rightfully saying there's no resource there - based on your screenshots you only have one resource, starting at /emp which has sub-resources for the CRUD operations at deeper paths.
Edit: On second look, your index.jsp is in WEB-INF. I don't think it should be based on the fact you appear to be trying to get a simple example together.
So, what do you expect to see at /JerseyRESTCRUD/?
https://graph.facebook.com/me/accounts?access_token=USERS_AUTH_TOKEN
returns a list of pages the user has admin status in (in JSON format).
I would like to list all the pages in a dropdownlist, and make the user choose which facebook page he wants to use (on my webapp), so I can obtain the specific access token for that facebook page.
My question is - whats the easiest and best way to do that. Ive never worked with JSON before, but I guess theres a pretty easy was to do this through the facebook-sdk.
Since you're using the C# SDK, just take the array of objects and convert them into a IList<IDictionary>() array using the pageId as the key and the value being the page name.
This is not fully compilable, but you get the idea:
private void IList<IDictionary<long,string>> ConvertToList(dynamic meAccounts)
{
foreach(var acc in meAccounts.data)
{
yield return new Dictionary((long)acc.id, (string)acc.name);
}
{
Okay figured out a way to do it. But I have no idea ifs the right way or the most optimal.
Would very much like inputs on it.
[DataContract]
internal class FacebookObj
{
[DataMember]
public List<FacebookAccount> data;
[DataMember]
public FacebookNext paging;
}
[DataContract]
internal class FacebookAccount
{
[DataMember]
public string name;
[DataMember]
public string category;
[DataMember]
public string id;
[DataMember]
public string access_token;
}
[DataContract]
internal class FacebookNext
{
[DataMember]
public string next;
}
public void ShowPages(string authToken) {
WebRequest webRequest = WebRequest.Create("https://graph.facebook.com/me/accounts?access_token=" + authToken);
WebResponse webResponse = webRequest.GetResponse();
Stream sr = webResponse.GetResponseStream();
if (sr != null)
{
jsonSer = new DataContractJsonSerializer(typeof(FacebookObj));
FacebookObj o = (FacebookObj)jsonSer.ReadObject(sr2);
foreach (FacebookAccount s in o.data)
{
//Do stuff
Response.Write(s.id + " - " + s.name + "<br />");
}
}
}
I have the following Play Framework entity (using Morphia for persistence) as part of a generic blogging app:
#Entity
public class Comment extends Model {
...
#Reference
#Indexed
public SiteUser commenter;
public static List<Comment> getLastCommentsByUsers(final List<SiteUser> users) {
final Query<Comment> query ds().createQuery(Comment.class);
query.field(commenter).hasAnyOf(users);
return query.asList();
}
}
SiteUser:
#Entity(noClassnameStored=true)
public class SiteUser extends AbstractUser {
public String realName;
}
AbstractUser:
public class AbstractUser extends Model {
#Indexed(value= IndexDirection.DESC, unique = true)
public String emailAddress;
#Required
public String password;
}
The method getLastCommentsByUsers() is supposed to return all comments by the users in the users parameter, but I always get an empty List back. The reason that Commment is a separate collection is to be able to retrieve last X Comments by certain users across their associated Posts, which isn't possible if the Comment is embedded in the Post collection.
Is there something wrong with my query (should I be using something other than hasAnyOf), or is it a problem with the relationship mapping - should I be using ObjectId instead?
I use the in() method with a list or set and its working perfectly. Here's a snippet:
List<String> keywordList;
List<Product> products = Product.find().field("keywords").in(keywordList).asList();
This should work for collection of embedded or references too.
You should use List<Key<SiteUser>> to query:
public static List<Comment> getLastCommentsByUsers(final List<SiteUser> users) {
final Query<Comment> query ds().createQuery(Comment.class);
query.field(commenter).hasAnyOf(toKeys(users)); // convert to keys
return query.asList();
}
public static List<Key<SiteUser>> toKeys(List<SiteUser> users) {
List<Key<SiteUser>> keys = new ArrayList<Key<SiteUser>>();
for(SiteUser user: users) {
keys.add(ds().getMapper().getKey(user));
}
return keys;
}
Or you can just get the keys by:
List<Key<SiteUser>> keys = ds().createQuery(SiteUser.class).query().filter(...).asKeyList();