mark mark - 3 months ago 9
reST (reStructuredText) Question

Restful url through property file

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

Answer

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.