Slide 1

Slide 1 text

1 Java Web Programming 1

Slide 2

Slide 2 text

2 Java as a Platform • Java is a set of software and specs developed by Sun and later acquired by Oracle • Java SE for Desktop • JRE does not come bundled with Windows or Mac OS X. In Linux, it depends on the distribution. • Java EE for Enterprise • Solid platform for developing backend services • Good compability with legacy systems • Web servers, application servers • Java ME for Mobile • Android uses Java language, but does not support Java ME! • Support today....? 2

Slide 3

Slide 3 text

3 Java Enterprise Edition • Java Enterprise Edition extends Java SE • Provides APIs and environment for "large-scale, multi-tiered, reliable and secure network applications". • Largely modular components running on application server • Uses heavily annotations • Also XML configurations can be used 3

Slide 4

Slide 4 text

4 Java EE Specifications • Java EE is defined by specifications • Some provider implements an API that meets this specification and can declare it's API as Java EE compliant • Several specifications • RMI, E-mail, Web services, EJBs, Servlets, JSPs .. • Java EE App Server handles securitys, scalability etc so developer can concentrate on business logic 4

Slide 5

Slide 5 text

5 Simple Web Application Clients (Browsers) HTTP Request HTTP Response Web Server 5

Slide 6

Slide 6 text

6 Java EE EJB Web Application HTTP Request JDBC HTTP Response Web Server Servlet + JSP EJB Container EJBs RMI / SOAP / REST Direct Method / RMI / SOAP / REST 6

Slide 7

Slide 7 text

7 Java Application Servers • IBM Websphere • Oracle Weblogic • Apache Geronimo • Oracle Glassfish • ... 7

Slide 8

Slide 8 text

8 Tomcat vs Glassfish • Tomcat is a HTTP server and Java Servlet container • GlassFish is a full-blown Java EE app server, including the servlet container • Tomcat is more lightweight, easier to admin • GlassFish is a reference implementation of Java EE specification so it should contain all the latest features 8

Slide 9

Slide 9 text

9 Tools to use for Java EE • Lot of choice between IDEs. Also it's possible to work in CLI! • There is no "best" IDE • Some IDEs • Eclipse • Netbeans • IntelliJ IDEA • IBM Rational Developer • Oracle JDeveloper 9

Slide 10

Slide 10 text

10 Quick Intro to Tools 10

Slide 11

Slide 11 text

11 What is Servlet? • It’s a specialized Java class, that handles HTTP Requests • extend HttpServlet • It will be instantiated it when needed, and removed from memory when it’s convenient • Server automatically runs servlet as threaded 11

Slide 12

Slide 12 text

12 Example: HelloWorld Servlet import java.io.*; import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.*; @WebServlet("/HelloWorldServlet") public class HelloServlet extends HttpServlet { public void doGet( HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("Hello World!"); out.println(""); out.println("

Hello World!

"); out.println(""); } } 12

Slide 13

Slide 13 text

13 WAR package • Web applications contain • Compiled Java bytecode (Servlets, JavaBeans) in WEB-INF/classes folder • JSP pages • HTML pages • Images (gif, jpeg, png) • JavaScript and CSS stylesheeets • Configuration files in WEB-INF/ folder • Any extra libraries in WEB-INF/lib folder • All these are packaged together by your tool to a single package file with .war extension • .war files may be used as is or packaged into .ear file • Both .war and .ear can be then deployed in any compatible application server – to update just deploy a new .war on top of the old one 13

Slide 14

Slide 14 text

14 Demo: Compiling and Deploying CLI 14

Slide 15

Slide 15 text

15 Labs CLI Compile and GlassFish 15

Slide 16

Slide 16 text

16 Labs Ant 16

Slide 17

Slide 17 text

17 HTTP CONNECTION 17

Slide 18

Slide 18 text

18 HTTP network protocol • HTTP is a network protocol of the Web • Hypertext Transfer Protocol • Delivers resources on the WWW • Usually delivered by TCP/IP • HTTP client sends a request to HTTP server • Default port is 80 • Resource can be a file or dynamically generated query result 18

Slide 19

Slide 19 text

19 Structure of HTTP • Consists of request and response • Format • an initial line, • zero or more header lines, • a blank line, • optional message body (this is the resource) • Example Header1: value1 Header2: value2 19

Slide 20

Slide 20 text

20 HTTP REQUEST: Initial Line • Initial line is different for the request than response. • Request line has three parts • method name, local path to resource, version of http • Example • GET /path/to/file/index.html HTTP/1.0 • Method name can be GET, POST, PUT, DELETE... 20

Slide 21

Slide 21 text

21 HTTP RESPONSE: Initial Line • The initial response line, called the status line • Typical status lines • HTTP/1.0 200 OK • HTTP/1.0 404 Not Found • Status code (200, 404) is computer-readable, reason phrase is human-readable • Status codes • 1xx, information message • 2xx, success • 3xx, redirect • 4xx, client error • 5xx, server error • See all status codes • http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 21

Slide 22

Slide 22 text

22 Header Lines • Header lines provide information about the request and response • Header-name: value • HTTP 1.0 provides 16 headers, HTTP 1.1 provides 46 headers • For example client should tell who is making the request • User-Agent: ... • Server should identify • Server: ... 22

Slide 23

Slide 23 text

23 Message Body • Message body contains the resource • Usually the message body includes header lines • Content-type: • MIME type of the resource, for example text/html, image/gif • Content-length • bytes 23

Slide 24

Slide 24 text

24 Example HTTP REQUEST and HTTP RESPONSE GET /MunSoftaniTestaus/MunHienoServlet HTTP/1.1 Host: localhost:8080 User-Agent: curl/7.49.1 Accept: text/html HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/plain;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:27:34 GMT Content-Length: 12 Hello World 24

Slide 25

Slide 25 text

25 Example HTTP REQUEST and HTTP RESPONSE POST /MunSoftaniTestaus/MunHienoServlet HTTP/1.1 Host: localhost:8080 User-Agent: curl/7.49.1 Accept: */* Content-type: text/plain Content-Length: 9 Some data HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/plain;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:39:58 GMT Content-Length: 10 Some data 25

Slide 26

Slide 26 text

26 Servlet Lifecycle • When request comes • Web container loads the servlet class • Creates an instance of the class • Calls init – method • Invokes service – method which invokes doGet, doPost ... • Only one instance of the object is created! • When several clients come, several threads are created • When container needs to remove the servlet, it calls destroy-method 26

Slide 27

Slide 27 text

27 Architecture http://www.tutorialspoint.com/servlets/servlets-life-cycle.htm 27

Slide 28

Slide 28 text

28 Servlet methods • doGet • if the servlet supports HTTP GET requests • doPost • for HTTP POST requests • doPut • for HTTP PUT requests • doDelete • for HTTP DELETE requests • init and destroy • to manage resources that are held for the life of the servlet • getServletInfo, which the servlet uses to provide information about itself 28

Slide 29

Slide 29 text

29 Example: init and destroy @WebServlet("/HelloWorld2Servlet") public class HelloWorld2Servlet extends HttpServlet { public void init(ServletConfig config) throws ServletException { // Initialize any long-lasting resources here } protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Handle any web requests here } public void destroy() { // Release any long-lasting resources here } } 29

Slide 30

Slide 30 text

30 Labs Lifecycle, Http POST and External file 30

Slide 31

Slide 31 text

31 Demo: Using IDE 31

Slide 32

Slide 32 text

32 Labs IDE 32

Slide 33

Slide 33 text

33 HttpServlet, HttpRequest, HttpSession 33

Slide 34

Slide 34 text

34 Request and Response public class HelloServlet extends HttpServlet { public void doGet( HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ... } } 34

Slide 35

Slide 35 text

35 javax.servlet.http.HttpServletRequest • Request object is representation of HTTP request • To get Form and / or Url parameters • getParameter and getParameterValues • Http Headers can be accessed via getHeader/getHeaders methods • Some of these have own methods • getRemoteUser(), getRequestURI(), getContentLength(), getContentType(), getLocale(), getLocales(), etc • See the API reference for more details 35

Slide 36

Slide 36 text

36 HttpServletRequest examples protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // What browser? String useragent = request.getHeader("User-agent"); // GET/POST? String method = request.getMethod(); // Query String? String queryString = request.getQueryString(); // Parameter name? String parameterName = request.getParameter("name"); } 36

Slide 37

Slide 37 text

37 javax.servlet.http.HttpServletResponse • HttpServletResponse for the Http Response • You can write headers: • addHeader(String name, String value) • To write stuff to client: • getWriter() or getOutputStream() depending on if you want to print encoded text or raw bytes • Remember to set content type! • Also possibility to set error codes 37

Slide 38

Slide 38 text

38 HttpServletResponse examples // Set content type, and force a character set response.setContentType("text/html; charset=iso-8859-1"); // Create PrintWriter for printing text or OutputStream for bytes PrintWriter out = response.getWriter() ; OutputStream os = response.getOutputStream(); // Redirect browser to immediately load a new page response.sendRedirect("http://www.somecompany.com/") ; 38

Slide 39

Slide 39 text

39 Common Mime-Types Content-type Description text/html HTML content for HTML, XHTML, HTML 5 text/xml Generic XML content text/plain Plaintext application/pdf PDF Document application/json JSON format application/vnd.ms- excel MS Excel file image/gif, image/jpeg, image/png GIF/JPEG/PNG-format image 39

Slide 40

Slide 40 text

40 Common HTTP Headers http://en.wikipedia.org/wiki/List_of_HTTP_header_fields Field name Description Example Accept Content-Types that are acceptable Accept: text/plain Accept-Charset Character sets that are acceptable Accept-Charset: utf-8 Accept-Encoding Acceptable encodings. See HTTP compression. Accept-Encoding: Accept-Language Acceptable languages for response Accept-Language: en-US Authorization Authentication credentials for HTTP authentication Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== Cache-Control Used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain Cache-Control: no-cache Connection What type of connection the user-agent would prefer Connection: close Cookie an HTTP cookie previously sent by the server with Set-Cookie (below) Cookie: $Version=1; Skin=new; Content-Length The length of the request body in octets (8-bit bytes) Content-Length: 348 Content-Type The mime type of the body of the request (used with POST and PUT requests) Content-Type: application/x-www-form-urlencoded Pragma Implementation-specific headers that may have various effects anywhere along the request-response chain. Pragma: no-cache Referer[sic] This is the address of the previous web page from which a link to the currently requested page was followed. (The word “referrer” is misspelled in the RFC as well as in most implementations.) Referer: http://en.wikipedia.org/wiki/Main_Page Refresh Used in redirection, or when a new resource has been created. This refresh redirects after 5 seconds. This is a proprietary, non-standard header extension introduced by Netscape and supported by most web browsers. Refresh: 5; url=http://www.w3.org/pub/WWW/People.html User-Agent The user agent string of the user agent User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) Via Informs the server of proxies through which the request was sent. Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) Warning A general warning about possible problems with the entity body. Warning: 199 Miscellaneous warning 40

Slide 41

Slide 41 text

41 Labs Request and Response 41

Slide 42

Slide 42 text

42 Cookies 42

Slide 43

Slide 43 text

43 Cookies • An HTTP cookie is a small piece of data sent from a website and stored on the user's computer • can be used to remember the state of web application, such as shopping cart in an online store. • Session cookie • Destroyed when browser is closed • Persistent cookie • Specific date when expires • Cookies are stored in browser • Structure is really simple: name, value and attributes (expiration date) 43

Slide 44

Slide 44 text

44 HTTP Request and Response GET /myservlet HTTP/1.0 Host: localhost:8080 HTTP/1.0 200 OK Content-type: text/html Set-Cookie: name=value; Expires=Wed, 09 Jun 2021 10:20:15 GMT 44

Slide 45

Slide 45 text

45 Http Request again GET /myservlet2 HTTP/1.0 Host: localhost:8080 Cookie: name=value 45

Slide 46

Slide 46 text

46 Servlet and Cookie • Creating a cookie Cookie c = new Cookie(name, value); response.addCookie(c); • Reading a cookie Cookie[] allCookies = request.getCookies(); 46

Slide 47

Slide 47 text

47 Labs Simple HTTP Cookie 47

Slide 48

Slide 48 text

48 Handling and validating HTML Forms 48

Slide 49

Slide 49 text

49 Example HTTP REQUEST and HTTP RESPONSE POST /MunSoftaniTestaus/MunHienoServlet HTTP/1.1 Host: localhost:8080 User-Agent: curl/7.49.1 Accept: */* Content-type: text/plain Content-Length: 9 Some data HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/plain;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:39:58 GMT Content-Length: 10 Some data 49

Slide 50

Slide 50 text

50 Example HTTP REQUEST and HTTP RESPONSE POST /MunSoftaniTestaus/MunHienoServlet HTTP/1.1 Host: localhost:8080 User-Agent: curl/7.49.1 Accept: */* Content-type: application/x-www-form-urlencoded Content-Length: ... name=vili&password=secret HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/plain;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:39:58 GMT Content-Length: 10 Login successful 50

Slide 51

Slide 51 text

51 Example Form Feedback Form Send Use either get or post The url where servlet is 51

Slide 52

Slide 52 text

52 Receiving Parameters @WebServlet("/GetAndPostServlet") public class GetAndPostServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String email = request.getParameter("email"); String output = "Name = " + name + "
E-mail = " + email; response.setContentType("text/html"); } } 52

Slide 53

Slide 53 text

53 Example Form Feedback Form Send Change to GET 53

Slide 54

Slide 54 text

54 After Submit When using GET, the user given input is transferred in url 54

Slide 55

Slide 55 text

55 Receiving Parameters @WebServlet("/GetAndPostServlet") public class GetAndPostServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); String email = request.getParameter("email"); String output = "Name = " + name + "
E-mail = " + email; response.setContentType("text/html"); } } 55

Slide 56

Slide 56 text

56 Form and Select Form Your car: Volvo Saab Mercedes Audi Send 56

Slide 57

Slide 57 text

57 Get Multiple Values public class GetAndPostServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... List cars = Arrays.asList(request.getParameterValues("cars")); String output = "Name = " + name + "
E-mail = " + email; for(String car : cars) { output += "
car = " + car; } } getParameterValues will return a String array 57

Slide 58

Slide 58 text

58 Lab POST + GET and Forms 58

Slide 59

Slide 59 text

59 Validation 59

Slide 60

Slide 60 text

60 Validation • Web app can be divided into three layers 1. Presentation (HTML) 2. Business Logic (Servlet, Java-classes) 3. Database • Layer 1 may validate user input • For example HTML5 Forms, JavaScript etc • Layer 2 always has to do validation • Before entering anything to database, check that user has given valid format. For example "school grade" could be a number between 4 – 10. • Layer 3 should do simple validation • By declaring column types to tables, you create very simple validation to the database 60

Slide 61

Slide 61 text

61 Layer 1: Validation
61

Slide 62

Slide 62 text

62 Layer 2: Validation • Check for not null! • Filter dangerous characters away, for example < and > might be dangerous because of html • If user gives <, replace it with <. And > for > • Watch out for SQL Injection • Use Regex for more advanced validation 62

Slide 63

Slide 63 text

63 Filter away HTML/XML public static String filterHtml(String input) { input = input.replace("<", "<"); input = input.replace(">", ">"); ... return input; } 63

Slide 64

Slide 64 text

64 SQL Injection • If user input is part of SQL – statement, you may run into trouble • String sql = "SELECT * FROM Customers WHERE UserId = " + userInput; • If user gives input • "1; DROP TABLE Customers" • Then we will have following SQL: • SELECT * FROM Customers WHERE UserId = 1; DROP TABLE Customers • Solution • Filter unwanted characters – may be not a very good idea • Use SQL parameters (JDBC: Prepared statements) 64

Slide 65

Slide 65 text

65 Regular Expressions • Designed to help working with strings in UNIX environment • Easy way to find a pattern in a string and/or replace it if you want • Very powerful tool • There are several different versions of Regex • Java Regex is very similar to regex found in Perl 65

Slide 66

Slide 66 text

66 Basic Syntax • In Regex, one uses patterns • Pattern can hold • Normal characters • Start and end indicators as ^ and $ • Count indicators like +, - , ? • Logical operators, like | • Grouping with {}, (), [] • Example (Perl-compatible) • /^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,5}$/ 66

Slide 67

Slide 67 text

67 Perl Regex Examples • Basic usage: /pattern/modifiers • Examples: • /ha jo/ matches "turha jono" • /ha jo/i matches "turha JONO"; 67

Slide 68

Slide 68 text

68 Some PERL regex rules REGEX Explanation Example . Any single character /a.c/ matches "abc" or "afc" [ ] Single character that is contained within the brackets /[abc]/ matches "a", or "b" or "c" ^ Find from the beginning of the string /^a/ matches "aku ankka" $ Find from the end of the string /a$/ matches "aku ankka" | OR /cat|dog/ matches "dog" or "cat" ^ NOT (when used in middle of pattern) /a^aa/ matches "aba" {n,m} Matches min n, max m /a{1,3}/ matches "a", or "aa", or "aaa" * Matches 0-n /a*/ ? Matches 0-1 /(hello)?/ + Matches 1-n /a+/ 68

Slide 69

Slide 69 text

69 Examples • /.ala/ • kavalampi • /\. Älä/ • Nyt se loppui. Älä rupea. • /^begin/ • begin starts like this. • /end$/ • this is the end 69

Slide 70

Slide 70 text

70 Examples • /^begin and end$/ • begin and end • /one|two|three/ • this is the one • /[abc]$/ • dkdkdka 70

Slide 71

Slide 71 text

71 More Perl REGEX Rules REGEX Explanation \w [a-zA-Z0-9_] \W ^[a-zA-Z0-9_] \n New Line \s Whitespace / Empty \S Not whitespaces / Empty \d Number \D Not Number 71

Slide 72

Slide 72 text

72 Examples • /^[+-]?\d+\.?\d*$/ • /^\d{1,2}\.\d{1,2}\.?\d{4}?$/ • /^(\d{1,2})\:(\d{1,2})\.(\d{1,2})$/ • /[CDE]:\\[\w]+\\[\w]+\\/ 72

Slide 73

Slide 73 text

73 Java Regex Example: We Found it! import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // REGEX Pattern pattern = Pattern.compile("jack"); Matcher matcher = pattern.matcher("xxx jack xxx"); if(matcher.find()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 73

Slide 74

Slide 74 text

74 Java Regex Example: Nope import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // REGEX Pattern pattern = Pattern.compile("^jack$"); Matcher matcher = pattern.matcher("jackjack"); if(matcher.find()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 74

Slide 75

Slide 75 text

75 Java Regex Example: We Found it! import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // REGEX Pattern pattern = Pattern.compile("^jack$"); Matcher matcher = pattern.matcher("jack"); if(matcher.find()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 75

Slide 76

Slide 76 text

76 Java Regex Example: We Found it! import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // REGEX \\. = . Pattern pattern = Pattern.compile("^[+-]?\\d+\\.?\\d*$"); Matcher matcher = pattern.matcher("+33.33"); if(matcher.find()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 76

Slide 77

Slide 77 text

77 Java Regex Example: We Found it! import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // REGEX Pattern pattern = Pattern.compile("(?i)tomaatti"); Matcher matcher = pattern.matcher("xxx TomAatti xxx"); if(matcher.find()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 77

Slide 78

Slide 78 text

78 Java Regex Example: nope import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // When using matches, it's ^tomaatti$ by default Pattern pattern = Pattern.compile("tomaatti"); Matcher matcher = pattern.matcher("xxx tomaatti xxx"); if(matcher.matches()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 78

Slide 79

Slide 79 text

79 Java Regex Example: We found it! import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // When using matches, it's ^tomaatti$ by default Pattern pattern = Pattern.compile("[a-z]"); Matcher matcher = pattern.matcher("a"); if(matcher.matches()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 79

Slide 80

Slide 80 text

80 Java Regex Example: We found it! import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexExample { public static void main(String[] args) { // When using matches, it's ^tomaatti$ by default Pattern pattern = Pattern.compile("tomaatti.*"); Matcher matcher = pattern.matcher("tomaattihellurei"); if(matcher.matches()) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 80

Slide 81

Slide 81 text

81 String.matches • Matcher creates precompiled regex and it's possible to reuse it • String has also matches(String regex) method but it will create the regex each time • Example public class RegexExample { public static void main(String[] args) { if("tomaattihellurei".matches("tomaatti.*")) { System.out.println("We found it!"); } else { System.out.println("nope"); } } } 81

Slide 82

Slide 82 text

82 Servlet and Regex public static final Pattern PATTERN = Pattern.compile("Yes|Excellent|Magnificent"); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain"); try (PrintWriter out = response.getWriter()) { String feedback = request.getParameter("userfeedback"); if(feedback != null) { Matcher matcher = PATTERN.matcher(feedback); if(matcher.matches()) { out.println("save to database"); } else { out.println("incorrect value."); } } } } 82

Slide 83

Slide 83 text

83 Lab Validation 83

Slide 84

Slide 84 text

84 JDBC Application connectivity to databases 84

Slide 85

Slide 85 text

85 JDBC Intro • Java Database Connectivity in Java since 1.1 • Platform independent, Database independen • Wide range of data sources possible: • SQL, spreadsheets, flat files • JDBC API • Estabish a connection to database • Execute SQL • Process the results 85

Slide 86

Slide 86 text

86 To use JDBC 1. Register driver 2. Access database 3. Do some SQL magic 4. Handle result 5. Close the connection 86

Slide 87

Slide 87 text

87 public static String jdbcConnection() { String result = ""; try { // 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") + "
"; } // 5. Close the connection rs.close(); statement.close(); conn.close(); } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } return result; } 87

Slide 88

Slide 88 text

88 About ResultSet rs.next(); rs.next(); rs.next(); // Prints "Williams" System.out.println(rs.getString("Last Name")); 88

Slide 89

Slide 89 text

89 executeUpdate String sql = "INSERT INTO ..."; Statement statement = conn.createStatement(); int numberOfRowsUpdated = statement.executeUpdate(sql); if(numberOfRowsUpdated > 0) { System.out.println("Updated successful!"); } 89

Slide 90

Slide 90 text

90 public static String jdbcConnection() { String result = ""; Connection conn = null; Statement statement = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost/test"); statement = conn.createStatement(); rs = statement.executeQuery("SELECT * FROM Clients"); } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } finally { try { if(rs != null) { rs.close(); } if(statement != null) { statement.close(); } if(conn != null) { conn.close(); } } catch(SQLException e) { e.printStackTrace(); } } return result; } The proper way of closing connection. 90

Slide 91

Slide 91 text

91 public static String jdbcConnection() { String result = ""; Connection conn = null; Statement statement = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost/test"); statement = conn.createStatement(); rs = statement.executeQuery("SELECT * FROM Clients"); } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } finally { try { // if(rs != null) { // rs.close(); // } if(statement != null) { statement.close(); } if(conn != null) { conn.close(); } } catch(SQLException e) { e.printStackTrace(); } } return result; } A ResultSet object is automatically closed when the Statement object that generated it is closed 91

Slide 92

Slide 92 text

92 public static String jdbcConnection() { String result = ""; try { Class.forName("com.mysql.jdbc.Driver"); // Java 7 autocloseable! try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test")) { // Java 7 autocloseable! try(Statement statement = conn.createStatement()) { ResultSet rs = statement.executeQuery("SELECT * FROM Clients"); while (rs.next()) { result += rs.getString("Firstname") + "
"; } } } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } return result; } Java 7 features autocloseable which closes the connection in right manner! 92

Slide 93

Slide 93 text

93 public static String jdbcConnection() { String result = ""; try { Class.forName("com.mysql.jdbc.Driver"); // Java 7 autocloseable! try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test"); { Statement statement = conn.createStatement()) { ResultSet rs = statement.executeQuery("SELECT * FROM Clients"); while (rs.next()) { result += rs.getString("Firstname") + "
"; } } } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } return result; } You can hook these into inside of one try(..). 93

Slide 94

Slide 94 text

94 // Java 7 autocloseable! try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test")) { // Java 7 autocloseable! try(Statement statement = conn.createStatement()) { ResultSet rs = statement.executeQuery("SELECT * FROM Clients"); ResultSetMetaData rsmd = rs.getMetaData(); int numCols = rsmd.getColumnCount (); result = ""; while (rs.next()) { result += ""; for (int i=1; i<=numCols; i++) { result += "" + rs.getString(i) + ""; } result += ""; } result += ""; } } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } If you don't know the column names you can use ResultSetMetaData 94

Slide 95

Slide 95 text

95 Transactions • If you want to commit several sql – commands into one: • conn.setAutoCommit(false); • // do some sql • conn.commit(); • conn.rollback(); 95

Slide 96

Slide 96 text

96 Prepared Statements • Prepared statement or parameterized statement is a feature used to execute the same or similar database statements repeatedly with high efficiency • Simple way to protect against SQL injection String sql = "UPDATE table1 set one = ?, two = ?"; PreparedStatement preStmt = con.prepareStatement(sql); preStmt.setInt(1, 123); preStmt.setString(2, "myNewValue2"); preStmt.executeUpdate();

Slide 97

Slide 97 text

97 Connection Pool 97

Slide 98

Slide 98 text

98 Creating and closing connections • In Servlet Context (Web App), opening when loading, closing when destroying • Problem: one connection is reserved for the whole lifespan of the app, what if you have multiple web apps doing the same thing? • In Servlet init and destroy – methods • Problem: one connection is reserved for the whole lifespan of the servlet, what if you have multiple servlets doing the same thing? • In doGet or doPost • Problem: creating and destroying the connection is expensive • Solution: Connection Pooling 98

Slide 99

Slide 99 text

99 Configuring Connection Pool • Connection Pool is provided by you by the app server (Glassfish) • You will have to create new connection pool and set a JNDI name for it • Java Naming and Directory (JNDI) service allow to look up services • Connection Pool is a service • App connects to JNDI and JDNI connects to the connection pool • It's possible to configure the connection pool and the app does not know about it! • To configure the 1) connection pool and 2) jndi – name, use glassfish admin web page or cli • Note: in Glassfish 4.1.1 the web admin is broken, use 4.1.0 or Payara 99

Slide 100

Slide 100 text

100 To Create new Connection Pool • PoolName: CanBeWhatEver • Resource Type: • DataSource (App Server Connection Pool) • ConnectionPoolDataSource (JDBC Driver pooling) • XADatasource (Distributed transaction for multiple databases) • SqlDriver (basic jdbc) 100

Slide 101

Slide 101 text

101 Example 101

Slide 102

Slide 102 text

102 Modify parameters 102

Slide 103

Slide 103 text

103 JNDI 103

Slide 104

Slide 104 text

104 public class ConnectionPool extends HttpServlet { private DataSource ds; public void init(ServletConfig config) throws ServletException { try { // JNDI Lookup can be slow, let's do it only one time. // You will have to specify the JNDI name in Glassfish admin! Context ctx = new InitialContext(); ds = (DataSource) ctx.lookup("MyDatabaseJNDI"); } catch (NamingException e) { e.printStackTrace(); } } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); try (PrintWriter out = response.getWriter()) { out.println(derbyConnection()); } } private String derbyConnection() { String result = "
";
String sql = "SELECT * FROM DUCKBURG_RESIDENTS";
// Let's ask the connection from the datasource!
try (Connection c = ds.getConnection()) {
try (Statement statement = c.createStatement()) {
ResultSet rs = statement.executeQuery(sql);
while (rs.next()) {
result += rs.getString("id") + " "
+ rs.getString("firstname") + " "
+ rs.getString("lastname") + "\n";
}
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
return result + "
"; } 104

Slide 105

Slide 105 text

105 Lab Connection pool 105

Slide 106

Slide 106 text

106 Java Persistence API 106

Slide 107

Slide 107 text

107 JPA • Java Persistence API (JPA) is an specification that describes management of relational data in apps using Java • The reference implementation for JPA is EclipseLink • http://www.eclipse.org/eclipselink/#jpa • Basic idea is simple, save objects to relational database 107

Slide 108

Slide 108 text

108 Quick Steps 1. Create persistence.xml file to meta-inf/ dir under your classes/ dir • This file declares for example what database (derby, mysql, ...) you are accessing 2. Annotate your POJO – class so that it JPA knows which table is used for storing the objects from this class 3. Implement the saving / retrieving using javax.persistence classes 108

Slide 109

Slide 109 text

109 org.eclipse.persistence.jpa.PersistenceProvider false 109

Slide 110

Slide 110 text

110 Annotations @Entity @Table(name="DUCKBURG_RESIDENTS") public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String firstname; private String lastname; public Person() {} public int getId() { return id; } 110

Slide 111

Slide 111 text

111 Code EntityManagerFactory factory = Persistence.createEntityManagerFactory("basicjpapu"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); Person p = new Person(); p.setFirstname("Mickey"); p.setLastname("Mouse"); // p.setId(7); em.persist(p); em.getTransaction().commit(); em.close(); 111

Slide 112

Slide 112 text

112 Entity • Annotate class with the @Entity • JPA will create a table for the entity • By default table name is class name • You can change this by using @Table annotation • Instances of the class will be a row in the table • All entity classes must define a primary key • You can auto-generate the primary key in the database using @GeneratedValue annotation 112

Slide 113

Slide 113 text

113 Annotations @Entity @Table(name = "employees") public class Employee { // Each pojo will have a primary // key which you annotate // by using @Id @Id @Column(name = "id") private int id; @Column(name = "firstname") private String firstName; @Column(name = "lastname") private String lastName; 113

Slide 114

Slide 114 text

114 Annotations @Entity @Table(name = "employees") public class Employee { // Each pojo will have a primary key which // you annotate // by using @Id @Id // Define strategy how to save this to db // IDENTIFY allow auto increment on demand in Derby/MySQL @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private int id; @Column(name = "firstname") private String firstName; @Column(name = "lastname") private String lastName; 114

Slide 115

Slide 115 text

115 Java Persistence Query Language • JPQL is a language defined in JPA specification • Based on SQL syntax • You work with classes and objects instead of records and fields • Template • SELECT ... FROM ... WHERE ... ORDER BY ... • Minimal JPQL Query • Select object FROM Employee as object • The FROM clause specifies query variable (like loop variable in programming) 115

Slide 116

Slide 116 text

116 In Code Query query = em.createQuery("Select obj from Employee as obj"); List list = query.getResultList(); 116

Slide 117

Slide 117 text

117 To delete Employee employee = em.find(Employee.class, id); em.remove(employee); 117

Slide 118

Slide 118 text

118 JPA and Connection Pool 118

Slide 119

Slide 119 text

119 persistence.xml org.eclipse.persistence.jpa.PersistenceProvider MyDatabaseJNDI false 119

Slide 120

Slide 120 text

120 Code @PersistenceContext(unitName = "persons") private EntityManager em; @Resource private UserTransaction userTransaction; public void doIt() { //EntityManagerFactory factory = Persistence.createEntityManagerFactory("persons"); //EntityManager em = factory.createEntityManager(); //em.getTransaction().begin(); try { userTransaction.begin(); Person p = new Person(); p.setFirstname("Jack"); p.setLastname("Smith"); em.persist(p); userTransaction.commit(); } catch(Exception e) { e.printStackTrace(); } } 120

Slide 121

Slide 121 text

121 EntityManager is not Thread Safe • In the previous code, EntityManager was declared as an attribute • When several threads are accessing the EntityManager at the same time, thing can go wrong • Usually the architecture is following • jsp (view) -> servlet (controller) -> EJB/JPA (Model) -> DB • When using the JPA in EJB, attributes are thread safe and you don't have to worry about it. Also transactions are handled for you. • In servlet, you will have to look up the EntityManager 121

Slide 122

Slide 122 text

122 @PersistenceContext(unitName="test-pu", name="persistence/em/test") public class TLInjectionServlet extends HttpServlet { @Resource private UserTransaction userTrx; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { EntityManager em = null; try { Context ic = new InitialContext(); em = (EntityManager) ic.lookup("java:comp/env/persistence/em/test"); } catch (NamingException e) { throw new ServletException(e); } try { userTrx.begin(); Employee employee = new Employee(...); em.persist(employee); userTrx.commit(); } catch (Exception e) { throw new ServletException(e); } } } 122

Slide 123

Slide 123 text

123 EJB Interface public interface JPAManager { public List getEmployees() throws Exception; } 123

Slide 124

Slide 124 text

124 Using EJB @Stateless public class DatabaseHandlerEJB implements JPAManager { @PersistenceContext(unitName = "employeedb") private EntityManager em; @Override public List getEmployees() throws Exception { Query query = em.createQuery("Select obj from Employee as obj"); return query.getResultList(); } } 124

Slide 125

Slide 125 text

125 Servlet public class DatabaseHandler extends HttpServlet { @EJB public JPAManager jpaManager; 125

Slide 126

Slide 126 text

126 REST

Slide 127

Slide 127 text

127 Rest • Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his theses: • http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_s tyle.htm • Way of providing interoperability between computer systems • Does not restrict communication to a particular protocol • Http Web Service API that follows REST principals are called RESTful APIs

Slide 128

Slide 128 text

128 What makes Rest a Rest? 1. Client – Server 2. Stateless 3. Cacheable 4. Layered system 5. Code on demand (optional) 6. Uniform Interface 1. Identification of resources 2. Manipulation of resources through representations 3. Self-descriptive messages 4. Hypermedia as the engine of application state

Slide 129

Slide 129 text

129 1. Client Server • Separate UI from the data improves portability of the UI • Improve scalability by simplifying server components • Both components, client and server, can evolve independently

Slide 130

Slide 130 text

130 2. Stateless • Client - server communication must be stateless in nature • No session data stored on the server • Each request from client to server must contain all the information necessary to understand the request

Slide 131

Slide 131 text

131 3. Cache • Responses should define themselves as cacheable or not • Eliminate client-server interactions • In Restful, you can do this by using HTTP Headers

Slide 132

Slide 132 text

132 Client Server Cache Client Cache Request contains all information Client may store the response to a cache and reuse it

Slide 133

Slide 133 text

133 4. Layered System • Rest can be built using multiple architecture layers • Restrict knowledge of the system to one layer • Client -> Cache -> middleware -> server -> db • For example the middleware can be a cache • Client cannot tell if it's connected to end server or middleware

Slide 134

Slide 134 text

134 5. Code on Demand (optional) • Client can download JavaScript, Flash or Java Applet from server • Server can decide how things are done

Slide 135

Slide 135 text

135 6. Uniform Interface • Uniform Interface has four constraints 1. Identication of resources • Every resource has unique URI 2. Manipulation of resources through representations • Representation can be in various formats and is de-coupled from the identification 3. Self-descriptive messages • Each message has enough information to describe how to process the message, for example by using content-type 4. Hypermedia as the engine of application state (HATEOAS) • Server respondes with a set of links what other actions are available

Slide 136

Slide 136 text

136 6.1 Identification of Resources • Every resource has it's own unique URI • http://company.com/employees/ • URI is an identifier • Result is the resource • Notice that resource is not 'storage object', it's entity • Resources are just some item that can be accessed

Slide 137

Slide 137 text

137 6.2 Representation • Identified resource can be returned in various formats, like HTML, XML, JSON, SVG, PNG • RESTful apps can send accept header where it defines what kind of data it can handle • Server can send Content-type where it defines the type of the resource • De-coupling the representation of the resource from the URI is key aspect of REST

Slide 138

Slide 138 text

138 6.3 Self-descriptive Messages • Each client and server response is a message • Message should be self-descriptive • Message contains the body and metadata • In Restful, you use HTTP GET, PUT and HTTP Headers for this

Slide 139

Slide 139 text

139 6.4 HATEOAS • In perfect you don't need documentation for the API • Include links to the responses • What other • REST client needs no prior information about the service • REST client enters app by simplex fixed URI • All future actions may be discovered within the response • Nearly ALL popular WEB APIs violate HATEOAS

Slide 140

Slide 140 text

140 HATEOAS (wikipedia) HTTP/1.1 200 OK Content-Type: application/xml Content-Length: ... 12345 100.00

Slide 141

Slide 141 text

141 Starbucks: Request HTTP POST /order latte

Slide 142

Slide 142 text

142 Starbucks: Response 201 CREATED Location: http://starbucks.com/order/1234 latte 3.00

Slide 143

Slide 143 text

143 Restful

Slide 144

Slide 144 text

144 Rest and Web Services • Web Service API that follows REST principals are called RESTful APIs • HTTP based RESTful APIs are defined with following aspects • base url • standard http methods

Slide 145

Slide 145 text

145 Example (wikipedia)

Slide 146

Slide 146 text

146 Example: REST + XML

Slide 147

Slide 147 text

147 Example: REST + XML

Slide 148

Slide 148 text

148 Example: REST + JSON

Slide 149

Slide 149 text

149 RESTful Design • Identify entities / resources • Create URI 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

Slide 150

Slide 150 text

150 Testing REST • When testing HTTP GET you can just 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

Slide 151

Slide 151 text

151 Rest Example: Hue

Slide 152

Slide 152 text

152 Lights on! HTTP PUT /api//lights/1/state { "on": true }

Slide 153

Slide 153 text

153 Response [ {"success": {"/lights/1/state/on": true}} ]

Slide 154

Slide 154 text

154 Lab Building REST with Node + Database

Slide 155

Slide 155 text

155 Best Practices

Slide 156

Slide 156 text

156 URLs and Actions • Identify resources • Use nouns, like ticket, user or group • Identify what actions can user apply to them • GET /employees/ • GET /employees/1 • POST /employees • PUT /employees/1 • DELETE /employees/1 • Use plurals in the endpoint name! • So do not: employee/1 vs employees/ • person / people vs goose / geese

Slide 157

Slide 157 text

157 Relations • Group logically relations • GET /threads/1/messages • GET /threads/1/messages/1 • POST /threads/1/messages

Slide 158

Slide 158 text

158 Update and Delete • When creating, updating return the updated resource to the client • In case of HTTP POST, return 201 and include Location Header that points to the URL of the resource • In case of HTTP DELETE • 204: no response body • 200: response body with the deleted resource

Slide 159

Slide 159 text

159 Status Codes • 200 OK (HTTP GET) • 201 Created (HTTP POST) • 204 No Content (For example Delete) • 400 Bad Request • 401 Unauthorized • 403 Forbidden • 404 Not Found • 405 Method not found (when method is not allowed for authenticated user) • 409 Conflict • 410 Gone (older apis) • 429 Too many requests

Slide 160

Slide 160 text

160 Errors • Return sensible HTTP status codes • 400 -> client issues • 500 -> server issues • Also send JSON explaining the error • { "code" : 1234, "message" : "Something bad happened :(", "description" : "More details about the error here" }

Slide 161

Slide 161 text

161 Lab Status codes, error handling

Slide 162

Slide 162 text

162 Pretty Print or Not? • If you don't have indentation and whitespaces it's hard to detect the structure of the response • Extra cost is data transfer, but it is really small cost if you use gzip

Slide 163

Slide 163 text

163 Caching • HTTP Provides built-in caching framework • Can be done both in client or in server-side

Slide 164

Slide 164 text

164 Lab Pretty Print and Caching

Slide 165

Slide 165 text

165 Filtering, sorting & searching • Use query parameters • Filtering • GET /employees?firstname=jack • Sorting • GET /employees?sort=firstname • Searching • GET /employees?q=jack • Combining • GET /employees?q=jack&sort=salary

Slide 166

Slide 166 text

166 Limiting • If full representation is not needed • GET employees?fields=firstname,lastname

Slide 167

Slide 167 text

167 Lab Filter and Sort

Slide 168

Slide 168 text

168 Authentication • Rest API should be stateless • Authentication should not depend on cookies or sessions • Each request should have some sort of authentication • By using SSL, you can send access token via HTTP Basic auth

Slide 169

Slide 169 text

169 Non-CRUD • What about operations that are not Create, Read, Update or Delete? • Can be fuzzy • PUT /employees/1/dosomething • POST /search

Slide 170

Slide 170 text

170 Documentation • API is only good as it's documentation • Well if you have really good API you don't need documentation (HATEOAS) • See GitHub • https://developer.github.com/v3/gists/#list-gists • See TAMK Open Data • http://avoindata.tamk.fi/en/

Slide 171

Slide 171 text

171 Consider Versioning • It's possible to version your API • Can be included in URL or in Header • Stripe uses version in URL and in header • curl https://api.stripe.com/v1/charges \ -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \ -H "Stripe-Version: 2017- 01-27" • https://stripe.com/docs/upgrades#api-changelog

Slide 172

Slide 172 text

172 JSON or XML • If creating Web Service, JSON is the way to go • If large number of enterprise customers, maybe XML is better • Lot of public Web APIs are dropping support to xml?

Slide 173

Slide 173 text

173 Rate limiting • By using status code 429 server can tell that the client has send too many requests in a given amount of time • Send headers like • X-Rate-Limit – number of allowed requests in current period • X-Rate-Remaining – number of remaining requests in the curren period • X-Rate-Limit-Reset – number of seconds left in the period

Slide 174

Slide 174 text

174 Lab Authentication

Slide 175

Slide 175 text

175 JAX-RS

Slide 176

Slide 176 text

176 JAX-RS • JAX-RS is API that provides support for creating 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)

Slide 177

Slide 177 text

177 JAX-RS Implementations • Implementations of JAX-RS include: • Jersey, the 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/

Slide 178

Slide 178 text

178 Java Annotation • Annotation is a metadata added to Java 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

Slide 179

Slide 179 text

179 JAX-RS Annotations • JAX – RS gives annotations where and plain old Java object (pojo) can be transformed to an resource that is accessed from URL • @Path • @GET, @PUT, @POST, @DELETE • @Produces • @Consumes

Slide 180

Slide 180 text

180 Resource import javax.ws.rs.GET; import javax.ws.rs.Produces; import javax.ws.rs.Path; // The Java 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 = "

Hello!

"; return result; } }

Slide 181

Slide 181 text

181 Resource Life Cycle • Resource instance is created for each 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

Slide 182

Slide 182 text

182 Deploying JAX-RS Service • You have couple choices to implement a starting point for your app 1. Extend Application to register root resources manually 2. Extend PackageResourceConfig to auto-scan paths

Slide 183

Slide 183 text

183 1) JAX-RS Application Model import java.util.HashSet; import java.util.Set; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; // http://localhost:8080/TestApp/rest/helloworld @ApplicationPath("/rest") public class MyApplication extends Application { @Override public Set> getClasses() { final Set> classes = new HashSet>(); // @Path("/helloworld") classes.add(HelloWorldResource.class); return classes; } }

Slide 184

Slide 184 text

184 2) ResourceConfig package fi.company.startingpoint; import javax.ws.rs.ApplicationPath; import org.glassfish.jersey.server.ResourceConfig; // http://localhost:8080/TestApp/rest/helloworld @ApplicationPath("/rest") public class MyApplication extends ResourceConfig { public MyApplication() { // Scanning packages for resources! packages("fi.company.resources"); } }

Slide 185

Slide 185 text

185 EXERCISE

Slide 186

Slide 186 text

186 Developing REST Resource

Slide 187

Slide 187 text

187 REST – recap (wikipedia)

Slide 188

Slide 188 text

188 @Path("/users/{id}") class User { String user1 = "1Jack"; String user2 = "2Tina"; String[] listOfUsers = {user1, user2}; @GET @Produces("text/xml") public String getUser(@PathParam("id") int id) { if(id >= 0 && id < listOfUsers.length) { return listOfUsers[id]; } else { return "invalid ID"; } } }

Slide 189

Slide 189 text

189 @Path Example @Path("/users") public class Users { // curl -X GET 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 + "'}"; } }

Slide 190

Slide 190 text

190 EXERCISE

Slide 191

Slide 191 text

191 JSON PARSING

Slide 192

Slide 192 text

192 @POST Example @Path("/users") class Users { // curl -X POST -d '{"id": 1, "firstname": "jack", "lastname": "pohjolainen"}' // http://localhost:8080/lab/users @POST public void addUser(String input) { ... } }

Slide 193

Slide 193 text

193 JSR 353: Java API for JSON • JSON is a 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

Slide 194

Slide 194 text

194 JSON • JSON defines only two data structures: objects and 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

Slide 195

Slide 195 text

195 JSON Example {"employees":[ {"firstName":"John", "lastName":"Doe"}, {"firstName":"Anna", "lastName":"Smith"}, {"firstName":"Peter", "lastName":"Jones"} ]}

Slide 196

Slide 196 text

196 JSR 353 Example String jsonText = "{\"key\": \"value\"}"; JsonReader reader = Json.createReader(new StringReader(jsonText)); JsonObject object = reader.readObject(); String name = object.getString("name");

Slide 197

Slide 197 text

197 Main Classes Class or Interface Description Json Contains static methods 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.

Slide 198

Slide 198 text

198 Creating Object Model @GET @Path("/json") @Produces(MediaType.APPLICATION_JSON) public String createJson() { JsonObjectBuilder builder = Json.createObjectBuilder(); builder.add("id", 1); builder.add("name", "jack"); JsonObject o = builder.build(); return o.toString(); }

Slide 199

Slide 199 text

199 Streaming API • Object Model API helps to convert JSON directly to generic objects, and requires reading document at once • If documents are large, or efficiency is the key, might be better to use Streaming API • Create a JsonParser, and parse a stream or 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

Slide 200

Slide 200 text

200 @Consumes • @Consumes annotation is used to specify which MIME type can be accepted from the client • So if your service consumes JSON, you can use JsonObject as an method argument

Slide 201

Slide 201 text

201 Example // curl -H "Content-Type: application/json" // -X POST -d '{"id": 1, "name": "jack"}' // http://localhost:8080/TestProject/rest/test/json @POST @Path("/json") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public JsonObject textProduces(JsonObject fromClient) { return fromClient; }

Slide 202

Slide 202 text

202 Testing > curl -H "Content-Type: application/json" -X POST -d '{"id": 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

Slide 203

Slide 203 text

203 EXERCISE

Slide 204

Slide 204 text

204 JAXB Converting POJO to JSON/XML and Back

Slide 205

Slide 205 text

205 XML and Java • How do you read and write 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 ->

Slide 206

Slide 206 text

206 Web Server Server.java Book.java class Book { .. } class ClientApp { public static void main(String [] args) { Book book = new Book("Tuntematon Sotilas"); sendToServer(book); } } Java 8 new features Client Computer ClientApp.java Book.java

Slide 207

Slide 207 text

207 JAXB • Java Architecture for XML Binding (JAXB) allows Java 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

Slide 208

Slide 208 text

208 JAX-RS and JAXB • Glassfish is bundled with Jersey (https://jersey.java.net/) which is a reference implementation of JAX-RS • In JAX-RS the mapping between POJO and XML is done automatic!

Slide 209

Slide 209 text

209 POJO @XmlRootElement class Planet { public int id; public String name; public double radius; }

Slide 210

Slide 210 text

210 Resource @Path("planet") class Resource { @GET @Produces(MediaType.APPLICATION_XML) public Planet getPlanet() { final Planet planet = new Planet(); planet.id = 1; planet.name = "Earth"; planet.radius = 1.0; return planet; } }

Slide 211

Slide 211 text

211 Result 1 Earth 1.0

Slide 212

Slide 212 text

212 MOXy • JSON binding is done by default a MOXy 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.

Slide 213

Slide 213 text

213 Resource @Path("planet") class Resource { @GET @Produces(MediaType.APPLICATION_JSON) public Planet getPlanet() { final Planet planet = new Planet(); planet.id = 1; planet.name = "Earth"; planet.radius = 1.0; return planet; } }

Slide 214

Slide 214 text

214 MOXy • EclipseLink MOXy component binds Java to JSON and 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/documentation/2.4/moxy/json 003.htm

Slide 215

Slide 215 text

215 BUILDING RESPONSES

Slide 216

Slide 216 text

216 HTTP Request GET /u/874087/books.xml HTTP/1.1 Host: dl.dropboxusercontent.com:443 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/ *;q=0.8 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

Slide 217

Slide 217 text

217 HTTP Response HTTP/1.1 200 cache-control: max-age=0 content-disposition: inline; filename="build.xml"; filename*=UTF- 8''build.xml content-encoding: gzip content-security-policy: referrer no-referrer content-type: application/xml date: Tue, 24 May 2016 07:10:09 GMT pragma: public server: nginx status: 200 x-content-security-policy: referrer no-referrer x-dropbox-request-id: 3179d488f019688a6649dda0711dc3fe x-robots-tag: noindex, nofollow, noimageindex x-server-response-time: 145 x-webkit-csp: referrer no-referrer HTTP Status 200 => OK 404 => Not Found ...

Slide 218

Slide 218 text

218 HTTP Status Codes and REST Code Meaning 200 OK Response to a succesful GET, PUT or DELETE 201 Created Response to a POST that results a creation 204 No Content Succesful request that won't return a body, like for example DELETE (DELETE can be 204 or 200) 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

Slide 219

Slide 219 text

219 WebApplicationException • It's possible to throw an Exceptions with the status code • throw new WebApplicationException(500); • Also predefined exceptions like • throw new InternalServerErrorException();

Slide 220

Slide 220 text

220 Response Builder • Another way to set the status code is to use Response • Change your method to return Response – object • Response – object may also hold the content of the HTTP response

Slide 221

Slide 221 text

221 Example of Response @Path("/test") public class TestResponse { @GET @Produces("text/plain") public Response testResponse() { Response.ResponseBuilder builder = Response.status(404); builder.entity("We failed to look for the entity."); Response response = builder.build(); return response; } }

Slide 222

Slide 222 text

222 HTTP Response HTTP/1.1 404 Not Found Content-Length: 33 Content-Type: text/plain 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.

Slide 223

Slide 223 text

223 Example of POST @Path("/customers") public class TestResponse { @POST @Path("/{id}") public Response testResponse(@PathParam("id") int id) { Response response; if(id >= 0) { // HTTP 201 Created Response.ResponseBuilder builder = Response.status(201); builder.entity("{'url': 'http://localhost:8080/TestProject/rest/test/" + id + "'}"); response = builder.build(); } else { // HTTP 400 Bad Request Response.ResponseBuilder builder = Response.status(400); response = builder.build(); } return response; } }

Slide 224

Slide 224 text

224 Testing curl -X POST http://localhost:8080/TestProject/rest/test/1 {'url': 'http://localhost:8080/TestProject/rest/test/1'} curl -X POST http://localhost:8080/TestProject/rest/test/-1 ... HTTP Status 400 - Bad Request

Slide 225

Slide 225 text

225 Shortcuts: HTTP 201 Created @GET @Path("/response") public Response response() { try { URI createdUri = new URI("http://.../rest/test/response/1"); return Response.created(createdUri).build(); } catch (URISyntaxException e) { e.printStackTrace(); throw new InternalServerErrorException("Invalid URI"); } }

Slide 226

Slide 226 text

226 HTTP Response HTTP/1.1 201 Created Content-Length: 0 Date: Sun, 29 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)

Slide 227

Slide 227 text

227 HTTP Location • The HTTP Location header field is returned 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

Slide 228

Slide 228 text

228 Shortcuts: HTTP 200 OK and Body @GET @Path("/response") @Produces(MediaType.APPLICATION_JSON) public Response response() { // Build JSON Response JsonObjectBuilder builder = Json.createObjectBuilder(); builder.add("name", "jack"); JsonObject jsonObject = builder.build(); // Create response with HTTP Status 200 ResponseBuilder responseBuilder = Response.ok(jsonObject, MediaType.APPLICATION_JSON); // Build and return the response Response response = responseBuilder.build(); return response; }

Slide 229

Slide 229 text

229 And even shorter ... @GET @Path("/response") @Produces(MediaType.APPLICATION_JSON) public Response response() { // Build JSON Response JsonObjectBuilder builder = Json.createObjectBuilder(); builder.add("name", "jack"); JsonObject jsonObject = builder.build(); return Response.ok(jsonObject, MediaType.APPLICATION_JSON).build(); }

Slide 230

Slide 230 text

230 And using POJOs @GET @Path("/response") @Produces(MediaType.APPLICATION_JSON) public Response response() { return Response.ok(new Employee(), MediaType.APPLICATION_JSON).build(); }

Slide 231

Slide 231 text

231 EXERCISE

Slide 232

Slide 232 text

232 HATEOAS • HATEOAS, Hypermedia as the Engine of Application State, 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

Slide 233

Slide 233 text

233 Example (wikipedia) GET /account/12345 HTTP/1.1 Host: somebank.org Accept: application/xml

Slide 234

Slide 234 text

234 Example (wikipedia) HTTP/1.1 200 OK Content-Type: application/xml 12345 100.00

Slide 235

Slide 235 text

235 Link Headers HTTP/1.1 200 OK Content-Type: application/xml Link: ; rel=deposit Link: ; rel=withdraw ... 12345 100.00

Slide 236

Slide 236 text

236 Building Links Link link = Link.fromUri("http://{host}/root/customers/") .rel("update") .build(); Response response = Response.noContent() .links(link) .build();

Slide 237

Slide 237 text

237 Query / Matrix Parameters

Slide 238

Slide 238 text

238 @Path • @Path can be used to define path elements, 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}")

Slide 239

Slide 239 text

239 Matrix vs Query params • Query params • http://some.where/thing?paramA=1&paramB=6542 • Matrix params • http://some.where/thing;paramA=1;paramB=6542

Slide 240

Slide 240 text

240 Matrix Params • Matrix params • http://some.where/thing;paramA=1;paramB=6542 • Advantages • 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

Slide 241

Slide 241 text

241 Example of Matrix and Query @Path("/class") public class MyResource { @Path("/matrix") @GET @Produces("text/plain") public String matrix(@MatrixParam("author") String author, @MatrixParam("title") String title) { String result = "matrix: author = " + author + " title = " + title; return result; } @Path("/query") @GET @Produces("text/plain") public String query(@QueryParam("author") String author, @QueryParam("title") String title) { String result = "query: author = " + author + " title = " + title; return result; } }

Slide 242

Slide 242 text

242 @Produces • The @Produces annotation is used to specify the 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

Slide 243

Slide 243 text

243 MIME Type • Two-part identifier for file formats transmitted on 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

Slide 244

Slide 244 text

244 JSON and XML • For JSON, use application/json • http://www.ietf.org/rfc/rfc4627.txt • 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. "

Slide 245

Slide 245 text

245 Example of Binary file public class MyResource { @Context ServletContext 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

Slide 246

Slide 246 text

246 EXERCISE