{"id":15724316,"url":"https://github.com/cedlemo/pochette","last_synced_at":"2025-03-31T01:14:20.028Z","repository":{"id":144939945,"uuid":"141753351","full_name":"cedlemo/pochette","owner":"cedlemo","description":"Just some JavaEE REST api tests","archived":false,"fork":false,"pushed_at":"2018-07-28T17:57:39.000Z","size":591,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-06T06:24:14.272Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cedlemo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-20T20:08:36.000Z","updated_at":"2018-07-28T17:57:40.000Z","dependencies_parsed_at":"2023-04-04T21:02:27.501Z","dependency_job_id":null,"html_url":"https://github.com/cedlemo/pochette","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Fpochette","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Fpochette/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Fpochette/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Fpochette/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cedlemo","download_url":"https://codeload.github.com/cedlemo/pochette/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246399798,"owners_count":20770908,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T22:16:09.264Z","updated_at":"2025-03-31T01:14:20.008Z","avatar_url":"https://github.com/cedlemo.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pochette\n\nLittle java web application to test Java EE + Mariadb + REST api + Ajax\n\n* [Install Mariadb driver and test connection](#install-mariadb-driver-and-test-connection)\n* [Create the DAL part](#create-the-dal-part)\n* [Handle DAL exceptions](#handle-dal-exceptions)\n* [Create a simple BLL](#create-a-simple-bll)\n* [Configure the REST interface](#configure-the-rest-interface)\n  * [Install the dependencies](#install-the-dependencies)\n  * [Configure the REST path](#configure-the-rest-path)\n  * [Create a resource class](#create-a-resource-class)\n  * [Return xml answer](#return-xml-answer)\n    * [Support the JAXB specification](#support-the-jaxb-specification)\n    * [Link class serializable in xml](#link-class-serializable-in-xml)\n    * [LinksManagement methods return Response objects](#linksmanagemenent-methods-return-response-objects)\n  * [Return response in json format](#return-response-in-json-format)\n    * [Install jackson library](install-jackson-library)\n    * [Specify the new supported format in the LinksManagement methods](#specify-the-new-supported-format-in-the-linksmanagemenent-methods)\n\n## Install Mariadb driver and test the connection.\n\nsee https://mariadb.com/kb/en/library/getting-started-with-the-java-connector/#using-the-jar-file-directly for reference.\n\n```bash\nmkdir -p ./WebContent/WEB-INF/lib\ncd WebContent/WEB-INF/lib\nwget https://downloads.mariadb.com/Connectors/java/connector-java-2.2.6/mariadb-java-client-2.2.6.jar\n```\n\nAdd this library in the build path and add the JUnit 5 library.\n\nthe tests\n\n```java\npackage fr.pochette.test;\n\nimport static org.junit.jupiter.api.Assertions.*;\n\nimport java.sql.Connection;\nimport java.sql.DriverManager;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport java.sql.Statement;\n\nimport org.junit.jupiter.api.Test;\n\nclass MariaDBConnection {\n\n\t@Test\n\tvoid test() {\n\t\tString url =\"jdbc:mariadb://localhost/\";\n\t\tString user = \"pochette_user\";\n\t\tString password = \"pochette_password\";\n\t\ttry (Connection conn = DriverManager.getConnection(url, user, password);\n\t\t\t\tStatement stmt = conn.createStatement(\n                //execute query\n                ResultSet rs = stmt.executeQuery(\"SELECT 'Hello World!'\");\n                //position result to first\n                rs.first();\n                d\u003ejavax.xml.bind\u003c/groupId\u003e\n    \u003cartifactId\u003ejaxb-api\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.sun.xml.bind\u003c/groupId\u003e\n    \u003cartifactId\u003ejaxb-core\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n   \u003cgroupId\u003ecom.sun.xml.bind\u003c/groupId\u003e\n   \u003cartifactId\u003ejaxb-impl\u003c/artifactId\u003e\n   \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ejavax.activation\u003c/groupId\u003e\n    \u003cartifactId\u003eactivation\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.1\u003c/version\u003e\n\u003c/dependency\u003eassertTrue(\"Hello World!\".equals(rs.getString(1))){));\n\t\t}\n\t\tcatch(SQLException e) {\n\t\t\tfail(\"La connection a échouée : \" + e.getLocalizedMessage());\n\t\t}\n\t}\n\n}\n```\n\n## Create the DAL part\n\nI only need for now to list all the links and see one link based on its id.\n\nIn the DAL package :\n* DAOFactory.java\n\n```java\npackage fr.pochette.dal;\n\npublic class DAOFactory {\n\tpublic static LinkDAO getLinkDAO() {\n\t\treturn new LinkDaoMariaDBJdbcImpl();\n\t}\n}\n```\n\n* LinkDAO.java\n\n```java\npackage fr.pochette.dal;\n\nimport java.util.List;\n\nimport fr.pochette.bo.Link;\n\npublic interface LinkDAO {\n\tpublic List\u003cLink\u003e listAll() ;\n\n\tpublic Link getLink(int id);\n}\n```\n\n* LinkDaoMariaDBJdbcImpl.java\n\n```java\npackage fr.pochette.dal;\n\nimport java.util.List;\n\nimport fr.pochette.bo.Link;\n\npublic class LinkDaoMariaDBJdbcImpl implements LinkDAO {\n\n\t@Override\n\tpublic List\u003cLink\u003e listAll() {\n\t\t// TODO Auto-generated method stub\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Link getLink(int id) {\n\t\t// TODO Auto-generated method stub\n\t\treturn null;\n\t}\n}\n```\n\nAdd the code to generate the requests:\n\n```java\npublic class LinkDaoMariaDBJdbcImpl implements LinkDAO {\n\n    public static final String SELECT_ALL_LINKS =\n        \"SELECT idLink, title, url, creationDate, consumed, l.idType as l_idType, label FROM LINKS l\"\n        + \" JOIN TYPES t ON l.idType = t.idType;\";\n\n    public static final String SELECT_LINK_BY_ID=\n        \"SELECT idLink, title, url, creationDate, consumed, l.idType as l_idType, label FROM LINKS l\"\n        + \" JOIN TYPES t ON l.idType = t.idType WHERE idLink=?;\";\n\n    @Override\n    public List\u003cLink\u003e listAll() {\n        List\u003cLink\u003e links = null;\n\ttry(Connection cnx = DBConnexionProvider.getConnection()){\n            links = _listAll(cnx);\n\t} catch (SQLException e) {\n            e.printStackTrace();\n\t}\n\treturn links;\n    }\n\n    public List\u003cLink\u003e _listAll(Connection cnx) throws SQLException {\n        List\u003cLink\u003e links = new ArrayList\u003cLink\u003e();\n        Statement st = cnx.createStatement();\n        ResultSet rs = st.executeQuery(SELECT_ALL_LINKS);\n        while(rs.next()) {\n            Link link = _buildLink(rs);\n            links.add(link);\n        }\n\tst.close();\n            return links;\n    }\n\n    @Override\n    public Link getLink(int id) {\n        Link link = null;\n        try(Connection cnx = DBConnexionProvider.getConnection()) {\n            link = _getLink(cnx, id);\n        } catch(SQLException e) {\n            e.printStackTrace();\n        }\n            return link;\n\t}\n\n     public Link _getLink(Connection cnx, int id) throws SQLException {\n        Link link = null;\n        PreparedStatement pstmt = cnx.prepareStatement(SELECT_LINK_BY_ID);\n        pstmt.setInt(1,  id);\n        ResultSet rs = pstmt.executeQuery();\n        while(rs.next()) {\n            link = _buildLink(rs);\n        }\n        pstmt.close();\n        return link;\n    }\n\n    private Link _buildLink(ResultSet rs) throws SQLException {\n        LinkType linkType = new LinkType(rs.getInt(\"l_idType\"), rs.getString(\"label\"));\n        Link link = new Link(rs.getInt(\"idLink\"),\n\t                     rs.getString(\"title\"),\n\t\t\t     rs.getString(\"url\"),\n                             rs.getDate(\"creationDate\").toLocalDate(),\n                             rs.getBoolean(\"consumed\"),\n                             linkType);\n        return link;\n    }\n}\n```\n\nThe database configuration is saved in the file *WebContent/META-INF/context.xml*.\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cContext\u003e\n\t\u003cResource\n\t\tname=\"jdbc/pool_cnx\"\n\n\t\tdriverClassName=\"org.mariadb.jdbc.Driver\"\n\t\ttype=\"javax.sql.DataSource\"\n\n\t\turl=\"jdbc:mariadb://localhost/POCHETTE_DB\"\n\t\tusername=\"pochette_user\"\n\t\tpassword=\"pochette_password\"\n\n\t\tmaxTotal=\"100\"\n\t\tmaxIdle=\"30\"\n\t\tmaxWaitMillis=\"10000\"\n\t/\u003e\n\n\u003c/Context\u003e\n```\n\n## Handle DAL exceptions:\n\nIn order to handle all the exceptions, there will be one generic exception that\nis used to catch all the dal exceptions via user defined error codes. Those\nerror codes will be later translated in readable message thanks to the\n`ErrorMessageReader` class coupled with the *error_messages.properties* file.\n\n* GenericException.java\n\n```java\npackage fr.pochette.exception;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class GenericException extends Exception{\n\n\tprivate static final long serialVersionUID = 1L;\n\n\tprivate List\u003cInteger\u003e errorCodes;\n\n\tpublic GenericException(){\n\t\tthis.errorCodes = new ArrayList\u003cInteger\u003e();\n\t}\n\n\tpublic void addError(int code) {\n\t\tthis.errorCodes.add(code);\n\t}\n\n\tpublic List\u003cInteger\u003e getErrorCodes(){\n\t\treturn this.errorCodes;\n\t}\n\n\tpublic boolean hasError() {\n\t\treturn this.errorCodes.size() \u003e 0;\n\t}\n}\n\n```\n\n* ErrorMessageReader.java\n\n```java\npackage fr.pochette.exception;\n\nimport java.util.ResourceBundle;\n\npublic class ErrorMessageReader {\n    private static ResourceBundle rb;\n\n    static {\n        try {\n            rb = ResourceBundle.getBundle(\"fr.pochette.exception.error_messages\");\n\t}\n\tcatch(Exception e)\n\t{\n\t    e.printStackTrace();\n\t}\n    }\n\n    public static String getMessage(int code)\n    {\n        String message=\"\";\n        try\n        {\n            if(rb!=null)\n            {\n                message=rb.getString(String.valueOf(code));\n    \t} else {\n                message=\"Something went wrong with the file that contains the error messages\";\n    \t}\n        } catch(Exception e) {\n            e.printStackTrace();\n            message=\"Unknown error\";\n        }\n\n        return message;\n    }\n}\n```\n\n## Create a simple BLL\n\nIn a package *fr.pochette.bll* the following file is added:\n\n* LinkManager.java\n\n```java\nimport java.util.List;\n\nimport fr.pochette.bo.Link;\nimport fr.pochette.dal.DAOFactory;\nimport fr.pochette.dal.LinkDAO;\nimport fr.pochette.exception.BusinessException;\n\npublic class LinkManager {\n\tprivate LinkDAO linkDAO;\n\n\tpublic LinkManager() {\n\t\tthis.linkDAO = DAOFactory.getLinkDAO();\n\t}\n\n\tpublic List\u003cLink\u003e listAll() throws BusinessException{\n\t\treturn this.linkDAO.listAll();\n\t}\n\n\tpublic Link getLink(int id) throws BusinessException {\n\t\treturn this.linkDAO.getLink(id);\n\t}\n}\n```\n\n## Configure the REST interface\n\n### Install the dependencies\n\nNow the project will be converted to a Maven project and in the *pom.xml* file\nthe implementation of the JAX-RS 2.0 specification will be specified so that\nMaven will be able to download the needed jars.\n\n* Right click on the Project \u003e Configure \u003e convert to Maven Project.\n    * Group Id : *Pochette*\n    * Artifact Id : *Pochette*\n    * Version : *0.0.1-SNAPSHOT*\n    * Packaging : *war*\n    * Pochette : *Pochette*\n\nThis will generate a pom.xml file in the root directory of the project. Now here\nis the part to add in order to use the Apache CXF implementation.\n\n```diff\ndiff --git a/pom.xml b/pom.xml\nindex 9b3e830..0eb5cc7 100644\n--- a/pom.xml\n+++ b/pom.xml\n@@ -5,6 +5,18 @@\n   \u003cversion\u003e0.0.1-SNAPSHOT\u003c/version\u003e\n   \u003cpackaging\u003ewar\u003c/packaging\u003e\n   \u003cname\u003ePochette\u003c/name\u003e\n+  \u003cdependencies\u003e\n+       \u003cdependency\u003e\n+       \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n+       \u003cartifactId\u003ecxf-rt-frontend-jaxrs\u003c/artifactId\u003e\n+       \u003cversion\u003e3.1.6\u003c/version\u003e\n+       \u003c/dependency\u003e\n+        \u003cdependency\u003e\n+       \u003cgroupId\u003eorg.apache.cxf\u003c/groupId\u003e\n+       \u003cartifactId\u003ecxf-rt-rs-http-sci\u003c/artifactId\u003e\n+       \u003cversion\u003e3.1.6\u003c/version\u003e\n+       \u003c/dependency\u003e\n+  \u003c/dependencies\u003e\n   \u003cbuild\u003e\n     \u003csourceDirectory\u003esrc\u003c/sourceDirectory\u003e\n     \u003cresources\u003e\n```\nIf the JDK version used is \u003e= 9 then it is necessary to add the following\ndependencies ([source](https://stackoverflow.com/questions/46920461/java-lang-noclassdeffounderror-javax-activation-datasource-on-wsimport-intellij )):\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ejavax.xml.bind\u003c/groupId\u003e\n    \u003cartifactId\u003ejaxb-api\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.sun.xml.bind\u003c/groupId\u003e\n    \u003cartifactId\u003ejaxb-core\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n   \u003cgroupId\u003ecom.sun.xml.bind\u003c/groupId\u003e\n   \u003cartifactId\u003ejaxb-impl\u003c/artifactId\u003e\n   \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ejavax.activation\u003c/groupId\u003e\n    \u003cartifactId\u003eactivation\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nAll the dependencies will be downloaded after the following actions:\n* right click on the project\n* select Maven\n* select Update Project\n\n### Configure the REST path\n\nIn the package *fr.pochette.rest*, a new class is created:\n\n```java\npackage fr.pochette.rest;\n\nimport javax.ws.rs.ApplicationPath;\nimport javax.ws.rs.core.Application;\n\n@ApplicationPath(\"/rest\")\npublic class ConfigurationApplicationREST extends Application {\n\n}\n```\n\nThis class will be detected by Tomcat and will be used as a configuration for\nthe REST application.\n\n### Create a resource class\n\nNow that there is a class that defines the root path of the REST application,\nI need to create a resource class that will manage the requests like GET, POST and so on\nfor the `Link` objects.\n\n*LinksManagement*\n\n```java\npackage fr.pochette.rest;\n\nimport java.util.List;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\n\nimport fr.pochette.bll.LinkManager;\nimport fr.pochette.bo.Link;\nimport fr.pochette.exception.BusinessException;\n\n@Path(\"/links\")\npublic class LinksManagement {\n\n\t@GET\n\tpublic String getLinks() {\n\t\tLinkManager linkManager = new LinkManager();\n\t\tString linkTitles = \"\";\n\t\ttry {\n\t\t\tList\u003cLink\u003e links = linkManager.listAll();\n\t\t\tfor(Link l : links) {\n\t\t\t\tlinkTitles += l.getTitle() + \"; \" ;\n\t\t\t}\n\t\t} catch (BusinessException e) {\n\t\t\tlinkTitles = \"An error occured \" + e.getLocalizedMessage();\n\t\t}\n\t\treturn linkTitles;\n\t}\n}\n```\n\nNow the connection with a browser to *http://localhost:8080/Pochette/rest/links*\nreturns :\n\n```\nDetecting use case of GADT with OCaml; Documentation OCaml; OCaml Mooc; Shahmen Poison; JJC De Mondoville Dominus Regnavit Mov. 4\u00265/6;\n```\n\n### Return xml answer\n\nIn order to be able to return xml anwsers, it is necessary to add support for the\nJAXB specification, to make the `Link` class easily serializable in xml and to\nmake the `LinksManagement` methods return some usable Http responses.\n\n#### Support for the JAXB specification\n\nThe JAXB APIs are considered to be Java EE APIs, and therefore are no longer contained on the default class path in Java SE 9. In Java 11 they are completely removed from the JDK.\n\nressources : [1](https://stackoverflow.com/questions/51564844/java-ee-rest-xml-support-javax-xml-bind-jaxbcontext-missing), [2](https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j)\n\nSo if you have Java 6/7 or 8, nothing has to be done to have access to the JAXB api. For Java 9, you can modify the pom.xml file with the following maven dependencies.\n\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ejavax.xml.bind\u003c/groupId\u003e\n        \u003cartifactId\u003ejaxb-api\u003c/artifactId\u003e\n        \u003cversion\u003e2.3.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.sun.xml.bind\u003c/groupId\u003e\n        \u003cartifactId\u003ejaxb-impl\u003c/artifactId\u003e\n        \u003cversion\u003e2.3.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.glassfish.jaxb\u003c/groupId\u003e\n        \u003cartifactId\u003ejaxb-runtime\u003c/artifactId\u003e\n        \u003cversion\u003e2.3.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ejavax.activation\u003c/groupId\u003e\n        \u003cartifactId\u003eactivation\u003c/artifactId\u003e\n        \u003cversion\u003e1.1.1\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nIf the Java version is equal to 10, the quick and dirty way is to add the following\ncommand-line option : `--add-modules java.xml.bind`.\n\nIn eclipse this can be done via:\n\n* Right click on the project\n* Run as\n* Run Configurations\n* Go on the Arguments panel\n* In the Vm arguments entry add with a space char ` --add-modules java.xml.bind`\n\n#### Link class serializable in xml\n\nThe two important things to note are:\n\n* the `@XmlRootElement` annotation: it defines the xml element that describes any *Link* object.\n* the presence of an empty constructor that is needed.\n\n##### *src/fr/pochette/bo/Link.java*\n\n```diff\ndiff --git a/src/fr/pochette/bo/Link.java b/src/fr/pochette/bo/Link.java\nindex 6fc94d5..b8293ef 100644\n--- a/src/fr/pochette/bo/Link.java\n+++ b/src/fr/pochette/bo/Link.java\n@@ -1,8 +1,14 @@\n package fr.pochette.bo;\n\n import java.time.LocalDate;\n\n-public class Link {\n+import javax.xml.bind.annotation.XmlRootElement;\n+\n+@XmlRootElement(name=\"link\")\n+public class Link {\n                int idLink;\n                String title;\n                String url;\n@@ -82,6 +88,12 @@ public class Link {\n                public void setLinkType(LinkType linkType) {\n                        this.linkType = linkType;\n                }\n+               /**\n+                *\n+                */\n               public Link() {\n+                       super();\n+               }\n                /**\n                 * @param idLink\n                 * @param title\n@@ -99,7 +111,4 @@ public class Link {\n                        this.setConsumed(consumed);\n                        this.setLinkType(linkType);\n                }\n-\n-\n-\n }\n```\n\n#### LinksManagement methods return Response objects\n\nPreviously, what was returned was basic java String objects. Now the objects returned\n are Response objects form *javax.rw.rs.core.Response*. This kind of object allows\n to specify the status of the Http response, and the object to use to fill the\n response body.\n\n ```java\npackage fr.pochette.rest;\n\nimport java.util.List;\n\nimport javax.ws.rs.GET;\nimport javax.ws.rs.Path;\nimport javax.ws.rs.PathParam;\nimport javax.ws.rs.Produces;\nimport javax.ws.rs.core.MediaType;\nimport javax.ws.rs.core.Response;\nimport javax.ws.rs.core.GenericEntity;\n\nimport fr.pochette.bll.LinkManager;\nimport fr.pochette.bo.Link;\nimport fr.pochette.exception.BusinessException;\n\n@Path(\"/links\")\npublic class LinksManagement {\n\n\t@GET\n\t@Produces(MediaType.APPLICATION_XML)\n\tpublic Response getLinks() {\n\t\tLinkManager linkManager = new LinkManager();\n\t\tList\u003cLink\u003e links = null;\n\t\ttry {\n\t\t\tlinks = linkManager.listAll();\n\t\t} catch (BusinessException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tGenericEntity\u003cList\u003cLink\u003e\u003e resultat = new GenericEntity\u003cList\u003cLink\u003e\u003e(links) {};\n\t\treturn Response\n\t\t\t\t.ok()\n\t\t\t\t.entity(resultat)\n\t\t\t\t.build();\n\t}\n\n\t@GET\n\t@Path(\"/{id : \\\\d+}\")\n\t@Produces(MediaType.APPLICATION_XML)\n\tpublic Response getLink(@PathParam(\"id\") int id) {\n\t\tLinkManager linkManager = new LinkManager();\n\t\tLink link = null;\n\t\ttry {\n\t\t\tlink = linkManager.getLink(id);\n\t\t} catch (BusinessException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\treturn Response\n\t\t\t\t.ok()\n\t\t\t\t.entity(link)\n\t\t\t\t.build();\n\t}\n}\n```\n\nNow every access to *http://localhost:8080/Pochette/rest/links* or *http://localhost:8080/Pochette/rest/links/1* will return an xml response:\n\n```xml\n\u003clink\u003e\n  \u003cconsumed\u003efalse\u003c/consumed\u003e\n  \u003ccreationDate/\u003e\n  \u003cidLink\u003e1\u003c/idLink\u003e\n  \u003clinkType\u003e\n    \u003cidType\u003e2\u003c/idType\u003e\n    \u003clabel\u003eDOCUMENTATION\u003c/label\u003e\n  \u003c/linkType\u003e\n  \u003ctitle\u003eDocumentation OCaml\u003c/title\u003e\n  \u003curl\u003ehttp://caml.inria.fr/pub/docs/manual-ocaml/\u003c/url\u003e\n\u003c/link\u003e\n```\n\n### Return response in json format\n\n#### Install jackson library\n\nIn order to be able to use the json format, we need the `jackson` library which\ncan be installed via the *pom.xml* file for maven.\n\n```diff\ndiff --git a/pom.xml b/pom.xml\nindex 336abbb..edc9b72 100644\n--- a/pom.xml\n+++ b/pom.xml\n@@ -37,6 +37,16 @@\n     \u003cartifactId\u003ejavax.activation-api\u003c/artifactId\u003e\n     \u003cversion\u003e1.2.0\u003c/version\u003e\n \u003c/dependency\u003e\n+ \u003cdependency\u003e\n+ \u003cgroupId\u003eorg.codehaus.jackson\u003c/groupId\u003e\n+ \u003cartifactId\u003ejackson-jaxrs\u003c/artifactId\u003e\n+ \u003cversion\u003e1.9.13\u003c/version\u003e\n+ \u003c/dependency\u003e\n+ \u003cdependency\u003e\n+ \u003cgroupId\u003eorg.codehaus.jackson\u003c/groupId\u003e\n+ \u003cartifactId\u003ejackson-xc\u003c/artifactId\u003e\n+ \u003cversion\u003e1.9.13\u003c/version\u003e\n+ \u003c/dependency\u003e\n   \u003c/dependencies\u003e\n   \u003cbuild\u003e\n     \u003csourceDirectory\u003esrc\u003c/sourceDirectory\u003e\n```\n\nThen right click on the project in eclipse, click on Maven, Update Project and\nthe dependencies will be downloaded.\n\n#### Specify the new supported format in the LinksManagement methods\n\nThe `@Produces` annotation supports an array of multiple `MediaType` :\n\n```diff\ndiff --git a/src/fr/pochette/rest/LinksManagement.java b/src/fr/pochette/rest/LinksManagement.java\nindex 2300860..c759b58 100644\n--- a/src/fr/pochette/rest/LinksManagement.java\n+++ b/src/fr/pochette/rest/LinksManagement.java\n@@ -18,7 +18,7 @@ import fr.pochette.exception.BusinessException;\n public class LinksManagement {\n\n        @GET\n-       @Produces(MediaType.APPLICATION_XML)\n+       @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})\n        public Response getLinks() {\n                LinkManager linkManager = new LinkManager();\n                List\u003cLink\u003e links = null;\n@@ -36,7 +36,7 @@ public class LinksManagement {\n\n        @GET\n        @Path(\"/{id : \\\\d+}\")\n-       @Produces(MediaType.APPLICATION_XML)\n+       @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})\n        public Response getLink(@PathParam(\"id\") int id) {\n                LinkManager linkManager = new LinkManager();\n                Link link = null;\n```\n\n#### Use Ajax to ask for the data in different formats\n\nThe problem now is to specify with format we need. For example every access with\nthe browser on *http://localhost:8080/Pochette/rest/links* will return data in the\nxml format.\n\nTo solve this, there is Ajax. The following example, is a web page that contains\na button and two selectors. The selectors configure the format of the data that\nwill be requested.\n\n* WebContent/listLinks.html\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n\u003cmeta charset=\"UTF-8\"\u003e\n\u003ctitle\u003eObtenir une réponse au format JSON\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\n\t\u003cdiv\u003e\n\t\u003cform \u003e\n\t\u003cfieldset\u003e\n\t\u003clegend\u003eSelect the format of the data\u003c/legend\u003e\n\t\u003cdiv\u003e\n\t\t\u003cinput type=\"radio\" checked id=\"xml\" name=\"dataFormat\"\u003e\n\t\t\u003clabel for=\"xml\"\u003exml\u003c/label\u003e\n\t\u003c/div\u003e\n\t\t\u003cdiv\u003e\n\t\t\u003cinput type=\"radio\"  id=\"json\" name=\"dataFormat\"\u003e\n\t\t\u003clabel for=\"json\"\u003ejson\u003c/label\u003e\n\t\u003c/div\u003e\n\t\u003c/fieldset\u003e\n\t\t\u003cinput type=\"button\" value=\"Ask for links\"  onclick=\"launchRequest()\"/\u003e\n\t\u003c/form\u003e\n\t\u003c/div\u003e\n\n\t\u003cdiv id=\"success\" style=\"color:green\"\u003e\u003c/div\u003e\n\t\u003cdiv id=\"failure\" style=\"color:red\"\u003e\u003c/div\u003e\n\n\t\u003cscript type=\"text/javascript\"\u003e\n\tfunction createXHR() {\n\t    if (window.XMLHttpRequest)    //  Objet standard\n\t    {\n\t        xhr = new XMLHttpRequest();     //  Firefox, Safari, ...\n\t    }\n\t    else if (window.ActiveXObject)      //  Internet Explorer\n\t    {\n\t        xhr = new ActiveXObject(\"Msxml2.XMLHTTP\");\n\t    }\n\t    return xhr;\n\t}\n\n\tfunction launchRequest()\n\t{\n\t    var xhr = createXHR();\n\t    xhr.onreadystatechange = function()\n\t    {\n\n\t    \tif (xhr.readyState == 4)\n\t        {\n\t            if (xhr.status == 200)\n\t            {\n\t            \tif(document.getElementById(\"xml\").checked)\n\t            \t\tsuccess(new XMLSerializer().serializeToString(xhr.responseXML));\n\t            \telse\n\t            \t\tsuccess(xhr.responseText);\n\t            }\n\t            else\n\t            {\n\t                if(document.getElementById(\"xml\").checked)\n                       \t    failure(xhr.status, xhr.responseXML);\n\t                else\n\t            \t    failure(xhr.status, xhr.responseText);\n\t            }\n\t        }\n\t    };\n\n\t    xhr.open(\"GET\", \"/Pochette/rest/links\", true);\n\t    if(document.getElementById(\"xml\").checked)\n\t    \txhr.setRequestHeader(\"Accept\",\"application/xml\");\n\t    else\n        \txhr.setRequestHeader(\"Accept\",\"application/json\");\n\t    xhr.send(null);\n\t}\n\n\tfunction success(response)\n\t{\n\t\tdocument.getElementById(\"success\").innerHTML=response;\n\t\tdocument.getElementById(\"failure\").innerHTML=\"\";\n\t}\n\n\tfunction failure(codeResponse, response)\n\t{\n\t\tdocument.getElementById(\"failure\").innerHTML=response;\n\t\tdocument.getElementById(\"success\").innerHTML=\"\";\n\t}\n\n\t\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nNote that the ajax requests are build here :\n\n```javascript\n\t    xhr.open(\"GET\", \"/Pochette/rest/links\", true);\n\t    if(document.getElementById(\"xml\").checked)\n\t    \txhr.setRequestHeader(\"Accept\",\"application/xml\");\n\t    else\n        \txhr.setRequestHeader(\"Accept\",\"application/json\");\n\t    xhr.send(null);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcedlemo%2Fpochette","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcedlemo%2Fpochette","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcedlemo%2Fpochette/lists"}