I am currently trying to build a RESTful API using raw JAX-RS. I have learned that when building REST APIs, there is the principle called HATEOAS(Hypermedia as the engine of application state). In my class we used Link Headers to tell the client, how to further progress the application. I have managed to implement all basic functionality and can access the server after deploying the application to a tomcat server.
My question now is, how do I add a header-link that contains a wildcard for the user to fill in, for example an id?
So far I have tried
#Path("/resources")
#Produces(MediaType.APPLICATION_JSON)
public Response listAllResources()
{
List<TestResource> resources = ...
// get stuff from database
return Response.ok(resources)
.link(UriInfo.getAbsolutePathBuilder().path("{id}").build(), "edit")
.build;
}
After I try to access the above defined path, I get an error message that the template variable id is undefined.
I can't find any helpful resource that shows me how to create a link header that looks like:
link: <http://example.com/api/resources/{id}>; rel: "edit"
I hope my question was clear enough since this is my first question on stackoverflow :)
Thanks in advance!
I found out, that links like in my example http://example.com/api/resources/{id} aren't possible by JAX-RS because the UriBuilder tries to resolve any URL part that's surrounded by curly braces. So just use like http://example.com/api/resources/:id, if you want to give an Uri Template. Unfortunately the client then has to do something like a String.replace() to actually "create" a valid URI.
Related
I am a Java developer, I want to write my own blogging application (that bloggers use to write their blogs with) i know it may sound crazy but i want it just for learning purpose, i am using JSF EJB Hibernate and RESTeasy tools,i started it i have created the database and the view.
From the information that i collected it is recommended to store the blog content in database(in html text), i find that i can use for that Javascript editor like CKEditor after the blogger write his blog in CKEditor i will concatenate it with a prepared header and footer after that i will store it in the database, and i found out that i can get blog post using RESTeasy API.
As an example(sorry):
after the blog is stored in the database
i want to present it to visitors like this:
link containing a path and the id of the article
<div>
Read More...
</div>
when the visitor press the link a REST Controller handle the request, fetch the article from the database using the provided id in the link and return an html page (without creating it statically).
The RESTeasy part perhaps something like this:
#Stateless
#Path("/article/")
public class ArticleResource {
#EJB
private ArticleService articleService;
#GET
#Path("/{id}")
#Produces(value = MediaType.TEXT_HTML)
public Response getArticleById(#PathParam("id") Long id){
//get article post from the database
Article article = articleService.findById(id);
//something here i didn't know
//return article post as an html page
}
}
Please if there is anything here that you see is wrong feel free to inform me, i am just learning here. And if there is an even better approach that you see is good, i really appreciate it.
I know perhaps using Spring it can be better but i want just to learn here how to do it.
I want to know how to get an html page stored in database using JAXRS,
the html page has no file in the application it is just stored in the database something like this:
"<html><head>...</head> <body>...content of the blog here</body> </html>"
Thank you in advance.
Use Jersey's MVC Templates
You can use freemarker as template engine to produce HTML with context
Your template will be similar to:
<html><head>...</head> <body> ${article.toString()}</body> </html>
You can follow example:
In this example, the FruitResource JAX-RS resource class is the controller. The Viewable instance encapsulates the referenced data model which is a simple String.
Furthermore, we also include a named reference to the associated view template – index.ftl.
In this example, we’ve used the #Template annotation. This avoids wrapping our model directly in a template reference via Viewable and makes our resource method more readable.
When developing a Web Application in Java, launching in Tomcat, I need to be able to create (dynamically) a new static address (link,URL) in the server that will be used to view the information of a new item, let's call it new_item_001, which have been just created by one user.
Say I want to create a new address
www.domain.com/webapp/items/new_item_001
which can be used to render a view of the contents of new_item_001.
Which is the best approach to do this?
Should I dynamically create a new servlet class for this view?
Should I dynamically create the folder items and one html file new_item_001 for this item inside of it?
Should I edit the server address mapping rules to create this static address and map it to a central servlet which somehow knows which item to display?
I understand the question is ill posed, and that I am far from even understanding the issue, so I would like some guidelines on what to look for.
None of the above.
You should simply have a servlet mapped to /items/*. When a request come to this servlet, analyze the actual path of the request, extract the part after /items/ to know the actual value (new_item_001) in your example, get the data corresponding to this item from the database, and send it to the browser.
Using a true MVC framework like Spring MVC would make that much easier. You could simply map a method of a controller using
#RequestMapping("/items/{itemId}")
public Item getItem(#PathVariable("itemId") String itemId) {
...
}
and let the framework do all the URL parsing for you.
I would like to tackle this in a simple way. Creating a servlet for each created item would be overkill and become quite cumbersome to manage after a successful run of the application for some time.
Changing/editing server mapping URL looks very naive approach and is not scaling too. Let configuration be there and change them only when you actually need to change them.
My suggestion is to create one servlet that handles all these requests. For example, you may save item information on a datastore or on file system(i.e images uploaded by user etc..). Next time a GET request is received by the application to fetch saved information of an item, servlet should be able to reference the item on database associated with the item id on the URL. If you don't wish to expose item id/surrogate key in the database, you can also have a simple mapping between them by implementing your own logic. Frameworks like Spring MVC do a good job in mapping URLs to resources like this should you wish to use a framework.
Additionally to minimize the number of requests to the same item, you can also implement an HTTP caching strategy(i.e. ETAG, If-Modified-Since) by instructing your web server at the time of first GET request from a user.
I am trying to create a restful-jersey webservice. I have to pass JSON object to the webservice.
#POST
#Path("/saveVehicleTrackingData")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.TEXT_PLAIN)
public String saveVehicleTrackingData(VehicleTracking vehicleTracking) {
return vehicleTracking.toString();
}
When I try try to make request to the service, it says HTTP Status 415 - Unsupported Media Type. Please help. Also, what should be the type of single argument of the method saveVehicleTrackingData.
PS: I am using POSTMAN to make http request. http://goo.gl/vwXNXQ
UPDATE :
As pointed out by peeskillet, the missing thing here is JSON Provider. The next challenge that I have is, how to integrate the JSON Provider in my project. After researching a little, I found FasterXML jackson as one of the JSON provider.
This image is just for reference. I just had it from another post.
Basically when you use raw, it will default to text/plain. The JSON in the drop down, is simply to select syntax highlighting. You still need to set the Content-Type header to application/json. You can click on the Headers button and add it.
For your first question:
What kind of hosting (Tomcat, GlassFish or whatever...) are you using, and what is the Java version of the host? I know from experience that different version of Tomcat in combination with Jersey sometimes gives problems with #Consumes(MediaType.APPLICATION_JSON).
About your second question:
You want to build a RESTful webservice, the right name for a path should be; VehicleTrackingData (or whatever you like). This path will work (request/response) with the known HTTP verbs; GET, POST, PUT or DELETE.
I have an Angular Controller, a factory service and a app.js.
There is also a MongoDB in the background. So i have a GET Method and it's already running very well. But how do i create a post method over HTTP?
So there is a formular as a html file. There are some CheckBoxes and input fields. AngularJS i use for the Frontend, in the background theres a JAVA Program.
You can use the below shorthand syntax for GET and POST requests:
GET: $http.get('/URL').success(successCallback);
POST: $http.post('/URL', data).success(successCallback);
Refer to this link for details on how to set different parameters. You may also have a look at tutorials here.
I am designing a REST API that I would like to be localizable in the future.
Therefore I am defining the URLs to be of the form
/en/<resource_url>
With the intention of being able to support
/fr/<resource_url>
In the future if need be.
However I only want to define each resource url service once. Therefore I figure I need to get the URL parsed and rewritten without the language piece of the URL before it is matched to services. Finally that language should be made available to the services somehow for them to localize if necessary.
How can I achieve this?
I am using Jersey 1.17 inside Jetty container embedded in a larger server process.
You can make the /en/ or the /fr/ part a variable. Then set your locale to the value of the variable. Here's an example:
#Path("/{locale}/username")
public class UserResource {
#GET
#Produces("text/xml")
public String getUser(#PathParam("locale") String locale) {
...
}
}
But that may not be the best way to go about it. After answering, I found this other SO question that is a better way to solve the problem: Getting the client locale in a jersey request With this way, you don't need to add this to the URL. Just make the client set a header.