By mark


2016-08-30 17:56:59 8 Comments

Hello all i have sample restful service below with jersey 2

MODEL Class

@XmlRootElement(name = "book")
@XmlType(propOrder = { "id", "name", "author", "price" })
public class Book {

private String id;
private String name;
private String price;
private String author;

public Book() {

}

public Book(String id, String name, String price, String author) {
    super();
    this.id = id;
    this.name = name;
    this.price = price;
    this.author = author;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPrice() {
    return price;
}

public void setPrice(String price) {
    this.price = price;
}

public String getAuthor() {
    return author;
}

public void setAuthor(String author) {
    this.author = author;
}

}

My DAOImpl

public class BooksImpl{
static Connection conn = null;
static Statement stmt;
ResultSet rs;

public List<Book> getAllBooks() throws SQLException, ClassNotFoundException, FileNotFoundException {
    getConnection();
    List<Book> arrBook = new ArrayList<Book>();
    rs = stmt.executeQuery(GET_ALL_BOOKS);
    while (rs.next()) {
        arrBook.add(new Book(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4)));
    }
    rs.close();
    stmt.close();
    conn.close();
    return arrBook;
}

Service

@Path("/library")
@Produces({ MediaType.APPLICATION_JSON + ";charset=UTF-8",MediaType.APPLICATION_XML + ";charset=utf-8" })
@Consumes({ MediaType.APPLICATION_JSON + ";charset=UTF-8",MediaType.APPLICATION_XML + ";charset=utf-8" })
public class BookServiceImpl implements BookService {

private BooksImpl booksImpl = new BooksImpl();

@GET
public Response getBooks(@QueryParam("format") String format) throws SQLException, ClassNotFoundException, FileNotFoundException {
    return Response.status(Status.OK).entity(new GenericEntity<List<Book>>(booksImpl.getAllBooks()) {
    }).header(HttpHeaders.CONTENT_TYPE, "XML".equalsIgnoreCase(format)
            ? MediaType.APPLICATION_XML + ";charset=UTF-8" : MediaType.APPLICATION_JSON + ";charset=UTF-8")
            .status(Status.OK).build();

}

So finally i make a get request say in a postman like ::

http://localhost:8080/BooksJAXRS/library

It's good and i can get the reponse by getting all the books from DB.

my web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>BooksJAXRS</display-name>
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.library.books</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>

My requriment is for different http methods we have different url end point paths for example

GET :  http://localhost:8080/BooksJAXRS/library
POST :  http://localhost:8080/BooksJAXRS/library
DELETE : http://localhost:8080/BooksJAXRS/library/1
PUT :  http://localhost:8080/BooksJAXRS/library/1

So i make a props file

GET=http://localhost:8080/BooksJAXRS/library
POST=http://localhost:8080/BooksJAXRS/library
DELETE= http://localhost:8080/BooksJAXRS/library/1
PUT= http://localhost:8080/BooksJAXRS/library/1

Now i want to capture that restful url and pass it through props file and route it accordingly depending on the method and url

Thank you Mark

2 comments

@Nicolas Filotto 2016-08-30 18:14:03

You could create 2 mappings on 2 different methods that call the same private method like this:

@Path("/")
...
public class BookServiceImpl implements BookService {

    @Path("/")
    @GET
    public Response getBooksByRoot(@QueryParam("format") String format) {
        return getBooks(format);
    }

    @Path("/library")
    @GET 
    public Response getBooksByLibrary(@QueryParam("format") String format) {
        return getBooks(format);
    }

    private Response getBooks(String format) {
        ...
    }

    @Path("/library")
    @POST 
    public Response createBook(@QueryParam("name") String name) {
        ...
    }

Response Update:

It seems that you want a dynamic mapping, so you need to use a Path with a regular expression.

@Path("/")
...
public class BookServiceImpl implements BookService {

    @Path("/{parameter:.*}")
    @GET
    public Response getBooks(@PathParam("parameter") String parameter) {
        if (properties.getProperty("GET").endsWith(parameter) {
            // code to get the books here
        } else {
            return Response.status(Response.Status.NOT_FOUND).build();
        }
    }

WARNING: The code snippet above is only meant to show the idea, it is not meant to be perfect. For example testing with endsWith could not be enough according to your context.

@mark 2016-08-30 18:42:33

Thank you.By the way by doing like this does the url will load through properties file?

@Nicolas Filotto 2016-08-30 18:44:35

I'm not sure I understand what you mean by "load through properties file", could you please clarify?

@mark 2016-08-30 18:49:47

I am sorry i will do that. When any client hit my url "localhost:8080/BooksJAXRS/library" it should go straight away to my properties file and from that properties file depending upon the url endpoint i.e. a GET request to /library should return all of my books,POST request to /library should create a new book etc

@Nicolas Filotto 2016-08-30 18:54:16

You simply map a new method with @Path("/library") as path but with also @POST, check my response update

@Roman Vottner 2016-08-30 18:57:08

@mark What is the property used for you want to read upon link invocation? Do you want to read the DB configuration and initialize a new DB connection on every request? This sounds like a veeeeery bad idea. I'm a bit confused by your specification TBH.

@mark 2016-08-30 19:07:08

I know thats a bad idea but that was my requirement.What ever request the end user make it should hit the properties file 1st and from there it should read the base path and then depending upon the resource requested example :/getAllBooks,/createbook,/DeleteBook it should be mapped to my service class.. @Roman

@mark 2016-08-30 19:08:07

@NicolasFilotto by doing that yes it works but i am not sure it will work with properties file

@Nicolas Filotto 2016-08-30 19:12:26

sorry I still don't get what you are supposed to do with the properties file, please update your question to add a concrete example because it is still unclear

@mark 2016-08-30 19:13:10

sure i will do it now

@mark 2016-08-30 19:23:07

@NicolasFilotto updated

@Nicolas Filotto 2016-08-30 19:26:48

whaoo you want a dynamic mapping, this is very bad in term of performances

@mark 2016-08-30 19:27:40

Ah yes i agree but thats the actual requirement i need :D

@Nicolas Filotto 2016-08-30 19:36:34

response updated, please check again

@PeterMmm 2016-08-30 18:15:54

When using standard web descriptor (url-pattern /*) and annotated end-points (@Path /library) there is not so much that can be done for dynamic (at runtime) routing at this points. If you want or need some dynamic routes, one option put the "app" into a new context like:

<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

And add some standard Servlet to forward to your desired end-points:

<servlet>
    <servlet-name>route</servlet-name>
    <servlet-class>my.package.Route</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>route</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

my.package.Route will be get hit on any other than /app/* request and you can do your routing to forward the request anywhere.

@mark 2016-08-30 19:12:24

it says java.lang.ClassNotFoundException: my.pack.route

@PeterMmm 2016-08-31 07:11:14

Of course, writing the servlet class is for you.

Related Questions

Sponsored Content

32 Answered Questions

[SOLVED] What exactly is RESTful programming?

  • 2009-03-22 14:45:39
  • hasen
  • 1613595 View
  • 3865 Score
  • 32 Answer
  • Tags:   http rest definition

21 Answered Questions

32 Answered Questions

[SOLVED] What is the difference between a field and a property?

  • 2008-11-17 08:41:38
  • Anonymous
  • 390517 View
  • 990 Score
  • 32 Answer
  • Tags:   c# properties field

33 Answered Questions

[SOLVED] PUT vs. POST in REST

  • 2009-03-10 14:25:20
  • alex
  • 2146180 View
  • 5037 Score
  • 33 Answer
  • Tags:   http rest post put

20 Answered Questions

13 Answered Questions

[SOLVED] How does the @property decorator work?

10 Answered Questions

[SOLVED] SOAP vs REST (differences)

7 Answered Questions

[SOLVED] Iterate through a HashMap

14 Answered Questions

[SOLVED] RESTful Authentication

12 Answered Questions

[SOLVED] RESTful URL design for search

  • 2008-10-16 04:51:20
  • Parand
  • 176179 View
  • 403 Score
  • 12 Answer
  • Tags:   rest

Sponsored Content