communication of two electronic devices over a network • Software function provided at a network address over a Web • There is no "official specification" for web services • Possible to identify two major classes 1. REST-complient Web Services 2. SOAP "Big" Web Services
response mechanism that allows client to access or modify data • It's machine to machine, not intented for the user • User uses web page via URL and receives HTML that the browser understands • http://openweathermap.org/find?q=Tampere • Computer app uses web service via URL and receives usually either XML or JSON • http://api.openweathermap.org/data/2.5/weather ?q=Tampere
Intranet • Uses usually either XML or JSON • XML is heavily used in in SOAP Web Services • Is not tied to any operating system or programming language • Is self-describing and discoverable
service • Specifies the location of the service • Specifies the operations of the service • Is written in XML and it's W3C recommendation • Description how to the service is called, what parameter it expects, what data structures it returns.
part of JAX-WS • Generates all necessary classes to contact the service! • Usage • wsimport -keep -verbose http://www.webservicex.net/stockquote.asmx?WSDL
between web services • Mandatory building blocks: • Envelope • Identifies the xml document as soap • Body • Call and response information • Usually SOAP envelope is transferred via HTTP
can be big • SOAP Web Services can be tricky to implement • XML is not compatible with data models of programming languages • REST Architecture is replacing SOAP Web Services?
style with uniform interface using URIs • Resources are manipulated with fixed set of HTTP calls • replace (HTTP PUT), read (HTTP GET), add (HTTP POST) and delete (HTTP DELETE) • No need for SOAP
Example URI • http://www.someapi.com/customers/1 • Can return data about client with ID 1 (either in XML or JSON) • Can also update/delete the customer with ID 1
to each resource • Categorize if resources are needed to view and/or update • All HTTP Get should be side-effect free • Put hyperlinks to resource representation to enable clients to drill down for more information • Specify the format of response data • Create documentation how to use the service
use browser • For more complicated services, you can use tools called cURL: http://curl.haxx.se/ • Via command line you can create HTTP GET, POST, DELETE, PUT commands: • curl GET http://localhost:8080/rest/cars • curl POST –d "{brand: 'skoda'}" http://localhost:8080/rest/cars • curl DELETE http://localhost:8080/rest/cars/0
Java SE • Lot of API Specs • RMI, Web Services, XML • Enterprise components • EJBs, Servlets, JSPs • Enterprise Apps run under a app server • Glassfish, JBoss, WebLogic, WebSphere ..
Microsystems for Java EE • Reference implementation of Java EE • Supports • JAX-RS, EJB, JavaServer Faces / Pages, RMI, Servlets etc.. • Allows developers to create enterprise apps that are portable and scalable • Download • https://glassfish.java.net/download.html
to be used to distribute collection of java servlets, xmls, htmls etc. • Must contain • /WEB-INF/web.xml • /WEB-INF/classes/SomeClass.class • web.xml defines the structure of your app. It's not needed in the most current versions of Java EE
.jar to classpath • classpath = where to find third-party classes • You can classpath when compiling • javac -classpath ".;/path/to/glassfish4/glassfish/modules/javax.ser vlet-api.jar" HelloServlet.java • Or add all Java EE libraries to classpath for easier access • set CLASSPATH = /path/to/glassfish4/glassfish/lib/*;/path/to/glass fish4/glassfish/modules/*
• Package these into war • jar -cf HelloServlet.war . • Deploy • asadmin deploy --force=true HelloServlet.war • Test on Browser: • http://localhost:8080/HelloServlet/helloworld • Test in CLI using CURL • curl -X GET http://localhost:8080/HelloServlet/helloworld
get complicated to give previous commands each time you make changes to your code. • Use ant (or other) for easier compiling and deploying • Create build.xmlthat holds information how to compile, create war, deploy and test • For example • ant compile • ant war • ant deploy • ant test
IDE • Netbeans, Eclipse, IntelliJ IDEA etc. • In Eclipse, install first GlassFish tools • Create dynamic web project and servlet • Choose "run on server"
errors about policy files, please start the server from command line using admin – rights: • > sudo asadmin start-domain • If running into deploy problems ("can't deploy"), then "Use JAR archives for deployment" – option • Right click on glassfish from eclipse server tab. Then, select Properties > Glassfishand [x] Use JAR archives for deployment
REST services • Uses annotations, introduces in Java SE 5 • Simplifies the process of implementing the services • JAX-RS 1.0 is a official part of Java EE 6 • JAX-RS 2.0 is a official part of Java EE 7 • In Glassfish no need to install anything • Can be downloaded separately (Jersey)
reference implementation from Oracle • http://jersey.java.net/ • RESTEasy, JBoss's implementation • http://www.jboss.org/resteasy • Apache CXF, an open source Web service framework • http://cxf.apache.org/docs/restful-services.html • Restlet, created by Jerome Louvel, a pioneer in REST frameworks • http://www.restlet.org/ • Apache Wink, Apache Software Foundation Incubator project, the server module implements JAX-RS • http://incubator.apache.org/wink/
source code • Built-in annotations • @Override, @Deprecated .. • Possible to create custom annotations • @CustomAnnotation("someString") • Annotation are often used by frameworks by giving special behaviour to your code • Annotation are parsed using annotation processors • These can create for example additional Java code from the annotations
class will be hosted at the URI path "/helloworld" @Path("/helloworld") public class HelloWorldResource { // The Java method will process HTTP GET requests @GET // The Java method will produce content identified by the MIME Media // type "text/html" @Produces("text/html") public String doSomething() { String result = "<html><head><title></title></head><body><h1>Hello!</h1></body></html>"; return result; } }
new request • Life-cycle of root resource classes is per-request • Very natural programming model where constructors and fields can be utilized without concern for multiple concurrent requests to the same resource • Possible to change the life cycle to for example @Singleton • Only one instance per jax-rs application
@ApplicationPath("/rest") public class MyApplication extends ResourceConfig { public MyApplication() { // Scanning packages for resources! packages("fi.tieturi.resources"); } }
at root level (class definition) or in method level • Class definition needs to have path, method definitions may have extra path to add • Paths are added to web app root context • http://server/webapp/resource/helloworld • Path may contain URI path templates, containing parameters • @Path("/users/{username}")
Can have more than one value: paramA=val1,val2 • No encoding and decoding & in XML • Can be anywhere in url, not just end • More readable? • Disadvantages • When submitting a FORM, query param is generated
MIME media types of representations a resource can produce and send back to the client • Can be defined at class level as default, or method level to override • Legal values are any mime types your implementation supports, typical choices are text/html, text/xml, text/plain
the internet • IANA official authority for th standardization • Composed of • type/subtype; optional parameters • Example • text/html; charset=UTF-8 • text/xml • text/plain • application/json • Top-level types: • application, audio, example, image, message, model, multipart, text, video
• For XML, use either text/xml or application/xml • http://www.rfc-editor.org/rfc/rfc3023.txt • "If an XML document -- that is, the unprocessed, source XML document -- is readable by casual users, text/xml is preferable to application/xml. " • "application/xml is preferable when the XML MIME entity is unreadable by casual users. "
context; @GET @Path("/image") @Produces("image/png") public byte[] getImage() { try { File configFile = new File(context.getRealPath("image.png")); return Files.readAllBytes(configFile.toPath()); } catch(Exception e) { e.printStackTrace(); throw new WebApplicationException(404); } } ... JAX-RS provides @Context for injecting variety of resources in REST By using the ServletContext, we can get a real path to a image file New I/O api introduces in Java 7 Serve 404 if not found
http://localhost:8080/Lab03/rest/users @GET @Produces("application/json") public String getUsers() { return "{result: 'HTTP GET all'}"; } // curl -X GET http://localhost:8080/Lab03/rest/users/1 @GET @Path("/{id}") @Produces("application/json") public String getUser(@PathParam("id") int id) { return "{result: 'HTTP GET with id ='" + id + "'}"; } // curl -X DELETE http://localhost:8080/Lab03/rest/users/1 @DELETE @Path("/{id}") @Produces("application/json") public String deleteUser(@PathParam("id") int id) { return "{result: 'HTTP DELETE with id ='" + id + "'}"; } }
data exchange format widely used in web services and other connected applications • JSR 353 provides an API to parse, transform, and query JSON data • There are several libraries for JSON parsing, but JSR 353 is preinstalled in Java EE • Also JAXB for automatic conversion between POJO and JSON
arrays • An object is a set of name-value pairs {} • An array is a list of values [] • JSON is often used as a common format to serialize and deserialize data in applications • RESTful web services use JSON extensively as the format for the data inside requests and responses • The HTTP header used to indicate that the content of a request or a response is JSON data is • Content-Type: application/json
to create JSON readers, writers, builders, and their factory objects. JsonGenerator Writes JSON data to a stream one value at a time. JsonReader Reads JSON data from a stream and creates an object model in memory. JsonObjectBuilder JsonArrayBuilder Create an object model or an array model in memory by adding values from application code. JsonWriter Writes an object model from memory to a stream. JsonValue JsonObject JsonArray JsonString JsonNumber Represent data types for values in JSON data.
genericobjects, and requiresreadingdocument at once • If documentsarelarge, or efficiency is the key, might be better to use StreamingAPI • Createa JsonParser, and parsea streamor String, • You can pull one event at time • Events are basically data structures, and you can do different handling based on data field name • When you need more events, you can say parser.next() • You can also write data using JsonGenerator
1, "name": "jack"}' http://localhost:8080/TestProject/rest/test/json {"id":1,"name":"jack"} > curl -H "Content-Type: application/json" -X POST -d 'THIS IS NOT JSON' http://localhost:8080/TestProject/rest/test/json exception The Content-Type entity- header field indicates the media type of the entity- body sent to the recipient
XML from Java? • Java API for XML Processing (JAXP) • Simple API for XML (SAX) • Event driven, only read • DOM Object Model (DOM) • Creates tree object in memory, read and manipulate • Java Architecture for XML Binding (JAXB) • Unmarshal xml file to Java objects • Marshal Java objects to xml file • JAXB available in Java SE 6 ->
ClientApp { public static void main(String [] args) { Book book = new Book("Tuntematon Sotilas"); sendToServer(book); } } <book> <title> Java 8 new features </title> </book> Client Computer ClientApp.java Book.java This image cannot currently be displayed.
developers • marshal Java objects to XML • unmarshal XML back to Java objects • JAXB is part of Java SE • Implementation is done by using annotations • Package: javax.xml.bind.annotation.*; • @XmlRootElement, @XmlElement • Separate tools available • xjc -> schema to classes • schemagen -> classes to schema
Old Java Objects) • In these cases JAXBElement wrapper objects are necessary to provide additional information • The xjc generated object model uses JAXBElement and therefore you need to way to construct these JAXBElement objects • ObjectFactory is for that • When using the ObjectFactory, unmarshaling is a bit complicated ...
library • In Glassfish this is bundled! • In Desktop you can use • jaxbMarshaller.setProperty("eclipse.media- type", "application/json" ); • But usually you don't need to because of JAX-RS Client API that handles automatic conversion of JSON to POJO and back.
back • http://www.eclipse.org/eclipselink/#moxy • JSON mapping differentiates datatypes • 1 => int, "hello" => String, true => boolean • JSON does not use attributes, @XmlAttribute is marshalled as an element • No Root element • See: • http://www.eclipse.org/eclipselink/documentati on/2.4/moxy/json003.htm
Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,fi;q=0.6 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 HTTP GET Request for a file books.xml
to a succesful GET, PUT or DELETE 201 Created Response to a POST that results a creation 205 No Content Succesful request that won't return a body like DELETE 404 Not Found Response when entity not found 400 Bad Request Response when request is incorrect 500 Internal Server Error Response when for example database connection fails
Date: Tue, 24 May 2016 07:36:51 GMT Server: GlassFish Server Open Source Edition 4.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1 Java/Oracle Corporation/1.8) We failed to look for the entity.
May 2016 09:04:16 GMT Location: http://.../rest/test/response/1 Server: GlassFish Server Open Source Edition 4.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1 Java/Oracle Corporation/1.8)
in responses from an HTTP server under two circumstances: • Ask a web browser to load different web page (URL Redirect). HTTP Status code should be 3xx redirection • Provide information about newly created resource. Http Status code should be 201
• Platform independent, Database independent • Wide range of data sources possible: • SQL, spreadsheets, flat files • JDBC API • Establish a connection to database • Execute SQL • Process the results
• To code in Java is always the same, changing the driver changes the connection to different database. • Lot’s of drivers for different databases: MySQL, Text, MS SQL Server..
• Type 1 that calls native code of the locally available ODBC driver. • Type 2 that calls database vendor native library on a client side. • Type 3, the pure-java driver that talks with the server-side middleware that then talks to database. • Type 4, the pure-java driver that uses database native protocol. • In most cases you can access the same database with four different type of drivers • List of drivers: • http://developers.sun.com/product/jdbc/drivers
no updatable result sets • JDBC 2.0 • Scrollable an updatable result sets • JDBC 3.0 was included in J2SE 1.4 • More metadata, named parameters in callable statements, some new datatypes • JDBC 4.0, Java SE 6 • Easier driver loading, RowSet for offline use, XML-support • JDBC 4.1, Java SE 7 • JDBC 4.2, Java SE 8
// 1. Register driver. Driver String is given to you by the driver // documentation. Driver (.jar) must be in classpath! Class.forName("com.mysql.jdbc.Driver"); // 2. Connect to database. Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test"); // 3. Some SQL Magic. Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery("SELECT * FROM Clients"); // 4. Handle Result while (rs.next()) { result += rs.getString("Firstname") + "<br>"; } // 5. Close the connection rs.close(); statement.close(); conn.close(); } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } return result; }
HTTP GET requests @GET // The Java method will produce content identified by the MIME Media // type "text/html" @Produces("text/html") public String jdbcConnection() { String result = ""; try { Class.forName("com.mysql.jdbc.Driver"); try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "root")) { try(Statement statement = conn.createStatement()) { ResultSet rs = statement.executeQuery("SELECT * FROM customers"); ResultSetMetaData rsmd = rs.getMetaData(); int numCols = rsmd.getColumnCount (); result = "<table>"; while (rs.next()) { result += "<tr>"; for (int i=1; i<=numCols; i++) { result += "<td>" + rs.getString(i) + "</td>"; } result += "</tr>"; } result += "</table>"; } } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); result += e.toString(); } return result; } } Note, In real life you should use connection pool which is provided by you by the app server
server side • JAX-RS 2.0 introduces easy way to communicate with REST backend • This client API also async support with callback mechanism for waiting the result from server • Also async support for server
of I/O threads • Server dedicates one thread from the pool • Process the request within the thread • Thread is released and put back to pool • Problem: huge number of requests and processing time-consuming -> all threads busy processing and pool is empty • Solution: Separate connection accepting and request processing to different threads
is a constraint for REST • REST client enters app using fixed URL • All future actions can be discovered within resource representations • JAX-RS 2.0 provides Link classes for the links provided by the server
• Response filters: after JAX-RS methods • By default for all HTTP Requests • By using filter it's possible for example to modify incoming request in some way • Or do some authentication
client "the hard way" • JAX-RS wraps the implementation of URLConnectionand provides easy way to communicate with RESTful backend • JAX-RS Client API is part of Java EE 7 • Client API reuses many aspects of JAX-RS
• ClientBuilder is used to create Client– objects • ClientBuilder.newClient() • Or use ClientBuilder.newBuilder() to give configuration properties • By using Client, you can create WebTarget that represents a specific URI • WebTarget target = client.target("http...."); • Invoke the request by using request() method which starts to build a request to client • Invocation.Builder b = client.request(); • Use get() – method to get the result
if (r.getStatus() == 200) { Customer customer = r.readEntity(Customer.class); } } finally { response.close(); } To free up resources, it's good practice to close Response
credentials, such as password • Web has standard protocols for authentication and Java EE support these • Authorization • Whether a certain user can access specific URI • You may allow PUT/POST/DELETE for others, and for others only GET • No web standard here, you need to configure your app server • Encryption • Use SSL, web defines https to leverage SSL and encryption • Usually these are not programming, it's all about configuration and applying annotations
Basic authentication features • BASIC • Just username/password in request header • GET /..., authorization: Basic username:password • DIGEST • Username/password under encryption • password is never used directly by the protocol • CERTIFICATE • Usage of certificate given by trusted organization • Or you can implement your own way of identifying users, like token-based
area • wildcards may be used • Set up user roles that can access URLs • Set up mode of authentication • See for example • http://java.boot.by/wcd-guide/ch05s03.html