{"id":20441,"date":"2014-01-16T01:00:39","date_gmt":"2014-01-15T23:00:39","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=20441"},"modified":"2014-01-15T12:21:54","modified_gmt":"2014-01-15T10:21:54","slug":"project-student-webservice-integration","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html","title":{"rendered":"Project Student: Webservice Integration"},"content":{"rendered":"<p>This is part of <a href=\"http:\/\/invariantproperties.com\/2013\/12\/10\/project-student\/\">Project Student<\/a>. Other posts are <a href=\"http:\/\/www.javacodegeeks.com\/2013\/12\/project-student-webservice-client-with-jersey.html\">Webservice Client With Jersey<\/a>, <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-server-with-jersey.html\">Webservice Server with Jersey<\/a>, <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-business-layer.html\">Business Layer<\/a>, <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-persistence-with-spring-data.html\">Persistence with Spring Data<\/a> and <a href=\"http:\/\/www.javacodegeeks.com\/2014\/01\/project-student-sharding-integration-test-data.html\">Sharding Integration Test Data<\/a>.<\/p>\n<p>Earlier we successfully ran integration tests for both the persistence\/business layer (using an embedded H2 database) and the REST server\/client layers (using a Jetty server). It\u2019s time to knit everything together.<\/p>\n<p>Fortunately we already have all of our code in place and tested. All we need to do now is create some configuration file magic.<br \/>\n&nbsp;<\/p>\n<h2>Limitations<\/h2>\n<ul>\n<li><strong>User authentication<\/strong> \u2013 no effort has been made to authenticate users.<\/li>\n<li><strong>Encryption<\/strong> \u2013 no effort has been made to encrypt communications.<\/li>\n<\/ul>\n<h2>Container-Managed Datasource and JNDI<\/h2>\n<p>Container-managed datasources have a bad reputation for many developers and I\u2019m not sure why. Confusion with Container-Managed Persistence (CMP), perhaps?<\/p>\n<p>In any case the idea behind a container-managed datasource is simple. You don\u2019t need to figure out how to maintain database connection parameters in a deployed system \u2013 no need to modify a deployed webapp (which is insecure) or read a file from the filesystem (which you may not be able to access), etc. You just hand the problem to the person maintaining the webserver\/appserver and retrieve the value via JNDI.<\/p>\n<p>Tomcat and Jetty require manual configuration in an XML file. More advanced appservers like JBoss and GlassFish allow you to configure datasources via a nice GUI. It doesn\u2019t really matter since you only have to do it once. Instructions for <a href=\"http:\/\/tomcat.apache.org\/tomcat-7.0-doc\/jndi-datasource-examples-howto.html\">Tomcat 7<\/a> and <a href=\"http:\/\/wiki.eclipse.org\/Jetty\/Howto\/Configure_JNDI_Datasource\">Jetty<\/a>.<\/p>\n<p>The key points for Tomcat are that the server library is under <em>$CATALINA_HOME\/lib<\/em> and that might not be where you expect. E.g., in Ubuntu it\u2019s <em>\/usr\/share\/tomcat7\/lib<\/em>, not <em>\/var\/lib\/tomcat7\/lib<\/em>. Second, if the <em>META-INF\/context.xml<\/em> file isn\u2019t picked up from the .war file you must place it under <em>conf\/Catalina\/localhost\/student-ws-webapp.xml<\/em> (or whatever you have named your .war file). The latter overrides the former so it\u2019s common to set up the .war file to run in the development environment and then override the configuration in the test and production environments.<\/p>\n<p><strong>META-INF\/context.xml<\/strong> (Tomcat)<\/p>\n<pre class=\" brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;Context&gt;\r\n\r\n    &lt;Resource name=\"jdbc\/studentDS\"\r\n        auth=\"Container\"\r\n        type=\"javax.sql.DataSource\"\r\n        driverClassName=\"org.postgresql.Driver\"\r\n        url=\"jdbc:postgresql:student\"\r\n        username=\"student\"\r\n        password=\"student\"\r\n        maxActive=\"20\"\r\n        maxIdle=\"10\"\r\n        maxWait=\"-1\"\r\n        factory=\"org.apache.commons.dbcp.BasicDataSourceFactory\" \/&gt;\r\n\r\n&lt;\/Context&gt;<\/pre>\n<p>It\u2019s worth noting that it\u2019s trivial to pass an encryption key via JNDI (as a java.lang.String). This has the same benefits as discussed earlier with regards to the need to modify a deployed webapp or access the server\u2019s filesystem.<\/p>\n<p>(The implementation is a little more complex since you want your actual encryption key to require both the JNDI key AND a filesystem-based salt but this is easy to handle during initial deployment of the webapp.)<\/p>\n<h2>JPA Configuration<\/h2>\n<p>Our <em>persistence.xml<\/em> file is extremely minimal. We\u2019ll typically want two persistence units, one for JTA transactions (production) and one for non-JTA transactions (development and testing).<\/p>\n<p><strong>META-INF\/persistence.xml<\/strong><\/p>\n<pre class=\" brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;persistence xmlns=\"http:\/\/java.sun.com\/xml\/ns\/persistence\"\r\n\txmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http:\/\/java.sun.com\/xml\/ns\/persistence \r\n   http:\/\/java.sun.com\/xml\/ns\/persistence\/persistence_1_0.xsd\"\r\n\tversion=\"1.0\"&gt;\r\n\r\n\t&lt;persistence-unit name=\"studentPU-local\"\r\n\t\ttransaction-type=\"RESOURCE_LOCAL\"&gt;\r\n\t\t&lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;\/provider&gt;\r\n\t\t&lt;non-jta-data-source&gt;jdbc\/studentDS&lt;\/non-jta-data-source&gt;\r\n\t&lt;\/persistence-unit&gt;\r\n&lt;\/persistence&gt;<\/pre>\n<h2>Web Configuration<\/h2>\n<p>The web.xml file is nearly identical to the one used in integration testing. The key difference is that it pulls in a resource reference for the container-provided datasource.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p><strong>WEB-INF\/web.xml<\/strong><\/p>\n<pre class=\" brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;web-app version=\"2.5\" xmlns=\"http:\/\/java.sun.com\/xml\/ns\/javaee\"\r\n    xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n    xsi:schemaLocation=\"http:\/\/java.sun.com\/xml\/ns\/javaee http:\/\/java.sun.com\/xml\/ns\/javaee\/web-app_2_5.xsd\"&gt;\r\n\r\n    &lt;display-name&gt;Project Student Webservice&lt;\/display-name&gt;\r\n\r\n    &lt;context-param&gt;\r\n        &lt;param-name&gt;contextClass&lt;\/param-name&gt;\r\n        &lt;param-value&gt;org.springframework.web.context.support.AnnotationConfigWebApplicationContext&lt;\/param-value&gt;\r\n    &lt;\/context-param&gt;\r\n    &lt;context-param&gt;\r\n        &lt;param-name&gt;contextConfigLocation&lt;\/param-name&gt;\r\n        &lt;param-value&gt;\r\n            com.invariantproperties.sandbox.student.config.PersistenceJpaConfig\r\n            com.invariantproperties.sandbox.student.config.BusinessApplicationContext\r\n            com.invariantproperties.sandbox.student.webservice.config.RestApplicationContext\r\n        &lt;\/param-value&gt;\r\n    &lt;\/context-param&gt;\r\n\r\n    &lt;listener&gt;\r\n        &lt;listener-class&gt;\r\n            org.springframework.web.context.ContextLoaderListener\r\n        &lt;\/listener-class&gt;\r\n    &lt;\/listener&gt;\r\n\r\n    &lt;servlet&gt;\r\n        &lt;servlet-name&gt;REST dispatcher&lt;\/servlet-name&gt;\r\n        &lt;servlet-class&gt;com.sun.jersey.spi.spring.container.servlet.SpringServlet&lt;\/servlet-class&gt;\r\n        &lt;init-param&gt;\r\n            &lt;param-name&gt;spring.profiles.active&lt;\/param-name&gt;\r\n            &lt;param-value&gt;test&lt;\/param-value&gt;\r\n        &lt;\/init-param&gt;\r\n    &lt;\/servlet&gt;\r\n\r\n    &lt;servlet-mapping&gt;\r\n        &lt;servlet-name&gt;REST dispatcher&lt;\/servlet-name&gt;\r\n        &lt;url-pattern&gt;\/rest\/*&lt;\/url-pattern&gt;\r\n    &lt;\/servlet-mapping&gt;\r\n\r\n    &lt;resource-ref&gt;\r\n        &lt;description&gt;Student Datasource&lt;\/description&gt;\r\n        &lt;res-ref-name&gt;jdbc\/studentDS&lt;\/res-ref-name&gt;\r\n        &lt;res-type&gt;javax.sql.DataSource&lt;\/res-type&gt;\r\n        &lt;res-auth&gt;Container&lt;\/res-auth&gt;\r\n    &lt;\/resource-ref&gt;\r\n&lt;\/web-app&gt;<\/pre>\n<h2>Spring Configuration<\/h2>\n<p>The Spring configuration for the persistence layer is dramatically different from before because of two changes. Stylistically, we can use a standard configuration file instead of a configuration class since we no longer have to deal with an embedded database.<\/p>\n<p>The more important change is that we\u2019ve moved all of the datasource configuration to the container and we can eliminate it from our spring configuration. We need to point to the right datasource and persistence unit and that\u2019s about it!<\/p>\n<p><strong>applicationContext-dao.xml<\/strong><\/p>\n<pre class=\" brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;beans xmlns=\"http:\/\/www.springframework.org\/schema\/beans\"\r\n    xmlns:context=\"http:\/\/www.springframework.org\/schema\/context\" xmlns:tx=\"http:\/\/www.springframework.org\/schema\/tx\"\r\n    xmlns:jpa=\"http:\/\/www.springframework.org\/schema\/data\/jpa\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n    xmlns:jee=\"http:\/\/www.springframework.org\/schema\/jee\"\r\n    xsi:schemaLocation=\"\r\n\r\nhttp:\/\/www.springframework.org\/schema\/beans\r\n\r\nhttp:\/\/www.springframework.org\/schema\/beans\/spring-beans-3.2.xsd\r\n\r\nhttp:\/\/www.springframework.org\/schema\/context\r\n\r\nhttp:\/\/www.springframework.org\/schema\/context\/spring-context-3.2.xsd\r\n\r\nhttp:\/\/www.springframework.org\/schema\/tx\r\n\r\nhttp:\/\/www.springframework.org\/schema\/tx\/spring-tx-3.2.xsd\r\n\r\nhttp:\/\/www.springframework.org\/schema\/data\/jpa\r\n\r\nhttp:\/\/www.springframework.org\/schema\/data\/jpa\/spring-jpa-1.3.xsd\r\n\r\nhttp:\/\/www.springframework.org\/schema\/jee\r\n\r\n       http:\/\/www.springframework.org\/schema\/jee\/spring-jee-3.0.xsd\"&gt;\r\n\r\n    &lt;context:property-placeholder location=\"WEB-INF\/database.properties\" \/&gt;\r\n\r\n    &lt;context:annotation-config \/&gt;\r\n\r\n    &lt;!-- we use container-based datasource --&gt;\r\n    &lt;jee:jndi-lookup id=\"dataSource\" jndi-name=\"${persistence.unit.dataSource}\"\r\n        expected-type=\"javax.sql.DataSource\" \/&gt;\r\n\r\n    &lt;bean name=\"entityManagerFactory\"\r\n        class=\"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean\"&gt;\r\n        &lt;property name=\"dataSource\" ref=\"dataSource\" \/&gt;\r\n        &lt;property name=\"persistenceUnitName\" value=\"${persistence.unit.name}\" \/&gt;\r\n        &lt;property name=\"packagesToScan\" value=\"${entitymanager.packages.to.scan}\" \/&gt;\r\n        &lt;property name=\"jpaVendorAdapter\"&gt;\r\n            &lt;bean class=\"org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter\" \/&gt;\r\n        &lt;\/property&gt;\r\n    &lt;\/bean&gt;\r\n\r\n    &lt;bean name=\"transactionManager\" class=\"org.springframework.orm.jpa.JpaTransactionManager\" \/&gt;\r\n\r\n    &lt;bean name=\"exceptionTranslation\"\r\n        class=\"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor\" \/&gt;\r\n\r\n    &lt;tx:annotation-driven transaction-manager=\"transactionManager\"\r\n        proxy-target-class=\"false\" \/&gt;\r\n\r\n&lt;\/beans&gt;<\/pre>\n<p>Our properties file just contains the name of the datasource, the persistence unit name, and the list of packages to scan that contain JPA annotations.<\/p>\n<p><strong>WEB-INF\/database.properties<\/strong><\/p>\n<pre class=\" brush:java\"># jpa configuration\r\nentitymanager.packages.to.scan=com.invariantproperties.sandbox.student.domain\r\npersistence.unit.dataSource=java:comp\/env\/jdbc\/studentDS\r\npersistence.unit.name=studentPU-local<\/pre>\n<h2>Database Schema and Security<\/h2>\n<p>Finally the integration tests can use Hibernate auto-creation but we should always explicitly maintain our schemas in a development and production environment. This allows us to maintain infrastructure values in addition to avoiding potential problems from automated tools acting in an unexpected manner.<\/p>\n<p>It\u2019s important to write and test both upgrade and downgrade scripts before going into production. We always need a way to recover gracefully if there\u2019s a problem.<\/p>\n<p>More importantly our database schema should always be owned by a different user than the webapp. E.g., the webapp may use \u2018student-user\u2019 for the tables created by \u2018student-owner\u2019. This will prevent an attacker using SQL injection from deleting or modifying tables.<\/p>\n<pre class=\" brush:java\">--\r\n-- for security this must run as student-owner, not student-user!\r\n--\r\n\r\n--\r\n-- create an idempotent stored procedure that creates the initial database schema.\r\n--\r\ncreate or replace function create_schema_0_0_2() returns void as $$\r\ndeclare\r\n    schema_version_rec record;\r\n    schema_count int;\r\nbegin\r\n    create table if not exists schema_version (\r\n        schema_version varchar(20) not null\r\n    );\r\n\r\n    select count(*) into schema_count from schema_version;\r\n\r\n    case schema_count\r\n        when 0 then\r\n            -- we just created table\r\n            insert into schema_version(schema_version) values('0.0.2');\r\n        when 1 then\r\n            -- this is 'create' so we only need to make sure it's current version\r\n            -- normally we accept either current version or immediately prior version.\r\n            select * into strict schema_version_rec from schema_version;\r\n            if schema_version_rec.schema_version  '0.0.2' then\r\n                raise notice 'Unwilling to run updates - check prior version';\r\n                exit;\r\n            end if;      \r\n        else\r\n            raise notice 'Bad database - more than one schema versions defined!';\r\n            exit;\r\n    end case;\r\n\r\n    -- create tables!\r\n\r\n    create table if not exists test_run (\r\n        test_run_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        name varchar(80) not null,\r\n        test_date timestamp not null,\r\n        username varchar(40) not null\r\n    );\r\n\r\n    create table if not exists classroom (\r\n        classroom_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        test_run_pkey int references test_run(test_run_pkey),\r\n        name varchar(80) not null\r\n    );\r\n\r\n    create table if not exists course (\r\n        course_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        test_run_pkey int references test_run(test_run_pkey),\r\n        name varchar(80) not null\r\n    );\r\n\r\n    create table if not exists instructor (\r\n        instructor_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        test_run_pkey int references test_run(test_run_pkey),\r\n        name varchar(80) not null,\r\n        email varchar(200) unique not null\r\n    );\r\n\r\n    create table if not exists section (\r\n        section_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        test_run_pkey int references test_run(test_run_pkey),\r\n        name varchar(80) not null\r\n    );\r\n\r\n    create table if not exists student (\r\n        student_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        test_run_pkey int references test_run(test_run_pkey),\r\n        name varchar(80) not null,\r\n        email varchar(200) unique not null\r\n    );\r\n\r\n    create table if not exists term (\r\n        term_pkey int primary key,\r\n        uuid varchar(40) unique not null,\r\n        creation_date timestamp not null,\r\n        test_run_pkey int references test_run(test_run_pkey),\r\n        name varchar(80) not null\r\n    );\r\n\r\n    -- correction: need to define this!\r\n    create sequence hibernate_sequence;\r\n\r\n    -- make sure nobody can truncate our tables\r\n    revoke truncate on classroom, course, instructor, section, student, term, test_run from public;\r\n\r\n    -- grant CRUD privileges to student-user.\r\n    grant select, insert, update, delete on classroom, course, instructor, section, student, term, test_run to student;\r\n\r\n    grant usage on hibernate_sequence to student;\r\n\r\n    return;\r\nend;\r\n$$ language plpgsql;\r\n\r\n-- create database schema\r\nselect create_schema_0_0_2() is null;\r\n\r\n-- clean up\r\ndrop function create_schema_0_0_2();<\/pre>\n<h2>Integration Testing<\/h2>\n<p>We can reuse the integration tests from the webservice service but I haven\u2019t copied them to this project since 1) I hate duplicating code and it would be better to pull the integration tests into a separate project used by both server and webapp and 2) it\u2019s easy to configure Jetty to supply JNDI values but for some reason the documented class is throwing an exception and it\u2019s not important enough (at this time) to spend more than a few hours researching.<\/p>\n<h2>Source Code<\/h2>\n<ul>\n<li>The source code is available at <a href=\"http:\/\/code.google.com\/p\/invariant-properties-blog\/source\/browse\/student\">http:\/\/code.google.com\/p\/invariant-properties-blog\/source\/browse\/student<\/a>.<\/li>\n<\/ul>\n<h2>Correction<\/h2>\n<p>The schema provided overlooked the \u2018hibernate_sequence\u2019 required to create new objects. It must be defined and readable by the \u2018student\u2019 user.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/invariantproperties.com\/2013\/12\/25\/project-student-webservice-integration\/\">Project Student: Webservice Integration<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Bear Giles at the <a href=\"http:\/\/invariantproperties.com\/\">Invariant Properties<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring Data and Sharding Integration Test Data. Earlier we successfully ran integration tests for both the persistence\/business layer (using an embedded H2 database) and the REST server\/client layers (using a Jetty server). It\u2019s time &hellip;<\/p>\n","protected":false},"author":113,"featured_media":148,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[106],"class_list":["post-20441","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-web-services"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Project Student: Webservice Integration<\/title>\n<meta name=\"description\" content=\"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Project Student: Webservice Integration\" \/>\n<meta property=\"og:description\" content=\"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2014-01-15T23:00:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Bear Giles\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bear Giles\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html\"},\"author\":{\"name\":\"Bear Giles\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/91196fd6369bac9f4ec7217ffbca53f9\"},\"headline\":\"Project Student: Webservice Integration\",\"datePublished\":\"2014-01-15T23:00:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html\"},\"wordCount\":879,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"keywords\":[\"Web Services\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html\",\"name\":\"Project Student: Webservice Integration\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"datePublished\":\"2014-01-15T23:00:39+00:00\",\"description\":\"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/01\\\/project-student-webservice-integration.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Project Student: Webservice Integration\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/91196fd6369bac9f4ec7217ffbca53f9\",\"name\":\"Bear Giles\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g\",\"caption\":\"Bear Giles\"},\"sameAs\":[\"http:\\\/\\\/invariantproperties.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Bear-Giles\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Project Student: Webservice Integration","description":"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html","og_locale":"en_US","og_type":"article","og_title":"Project Student: Webservice Integration","og_description":"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring","og_url":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2014-01-15T23:00:39+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","type":"image\/jpeg"}],"author":"Bear Giles","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Bear Giles","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html"},"author":{"name":"Bear Giles","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/91196fd6369bac9f4ec7217ffbca53f9"},"headline":"Project Student: Webservice Integration","datePublished":"2014-01-15T23:00:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html"},"wordCount":879,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","keywords":["Web Services"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html","url":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html","name":"Project Student: Webservice Integration","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","datePublished":"2014-01-15T23:00:39+00:00","description":"This is part of Project Student. Other posts are Webservice Client With Jersey, Webservice Server with Jersey, Business Layer, Persistence with Spring","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2014\/01\/project-student-webservice-integration.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Project Student: Webservice Integration"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/91196fd6369bac9f4ec7217ffbca53f9","name":"Bear Giles","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c4e8f47b520b4147cb7f173f9d78cf8862974fdeeff4baea9d6a632cf7b1b54c?s=96&d=mm&r=g","caption":"Bear Giles"},"sameAs":["http:\/\/invariantproperties.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Bear-Giles"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20441","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/113"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=20441"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/20441\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/148"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=20441"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=20441"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=20441"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}