Presentation is loading. Please wait.

Presentation is loading. Please wait.

Bare-knuckle web development Odessa Johannes Brodwall, Chief scientist Exilesoft Global.

Similar presentations


Presentation on theme: "Bare-knuckle web development Odessa Johannes Brodwall, Chief scientist Exilesoft Global."— Presentation transcript:

1 Bare-knuckle web development Odessa Johannes Brodwall, Chief scientist Exilesoft Global

2 Bare-knuckle philosophy Demonstration of bare- knuckle web in Java Further directions

3 Part I:

4 The bare-knuckle philosophy

5 High impact/low ceremony Framework light Test-driven

6 High impact with low ceremony

7 Java web: Servlets, WebDriver, Jetty, Mockito

8 Java SOAP: JOOX, HttpURLConnection

9 .NET web prototype: WebDriver + HttpListener

10 .NET web work-in- progress: WebDriver + HttpSelfHostServer

11 Light on framework

12 Frameworks solve 80% of the job…

13 … and makes the rest 10 times as hard

14 “Why did Hibernate suddenly slow down?”

15 “How do I implement a custom SOAP header with JAX-WS?”

16 “How to do X with Spring”

17 @AutoWire + package scan with 100s of beans

18 Test-driven

19 No more architecture than what’s needed

20 Fast feedback cycle – also in the future

21 Part II:

22 Demo: Phonebook web app

23 Test driving

24 WebDriver browser = createWebDriver(); browser.get(url); browser.findElement(By.linkText("Add contact")).click(); browser.findEleme(By.name("fullName")).sendKeys("Vader"); browser.findEleme(By.name("phoneNumber")).sendKeys("27"); browser.findEleme(By.name("saveContact")).click(); browser.findElement(By.linkText("Find contact")).click(); browser.findElem(By.name("nameQuery")).sendKeys("vader"); browser.findElement(By.name("nameQuery")).submit(); assertThat(browser.findElem(By.id("contacts")).getText()).contains("555-33274-7827");

25 Server server = new Server(0); server.setHandler( new WebAppContext("src/main/webapp", "/contacts")); server.start(); int port = server.getConnectors()[0].getLocalPort(); String url = "http://localhost:" + port + "/contacts";

26 contactServlet com.exilesoft.bareknuckleweb.ContactServlet contactServlet contact/*

27 public class ContactServlet extends HttpServlet { }

28 @Test public void shouldShowAddForm() throws Exception { ContactServlet servlet = new ContactServlet(); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse resp = mock(HttpServletResponse.class); StringWriter html = new StringWriter(); when(resp.getWriter()).thenReturn(new PrintWriter(html)); when(req.getPathInfo()).thenReturn("/create.html"); servlet.doGet(req, resp); verify(resp).setContentType("text/html"); assertThat(html.toString()).contains("<form method='post'").contains("<input type='text' name='fullName'").contains("<input type='text' name='phoneNumber'").contains("<input type='submit' name='createContact'"); }

29 Refactoring

30 Part III:

31 Further directorions

32 Norwegian agricultural authority

33 Java web application with an MVC architecture

34 Controllers: Create a view Retrieve model from repo Set model on view Render view

35 View example:

36 @Override public void render(HttpServletResponse resp) throws IOException { Match document = $("html", head(), $("img").attr("src", "/sms-varsel/Sparebank1.jpg"), $("h1", "Internet bank simulator"), $("form").attr("method", "post").append( hiddenField(this.bankNum, "bankNum"), hiddenField(this.customerId, "customerId"), $("h2", "Set Mobile Phone Number"), phoneNumberField(this.phoneNumber), $("h2", "Account numbers"), accountNumbersField(this.accountNumbers), $("h2", "Payment account"), paymentAccountField(this.defaultAccount), $("h2", "Save changes"), $("div", $("input").attr("type", "submit").attr("value", "Store")).attr("name", "update"))); resp.setContentType("text/html"); resp.setCharacterEncoding("UTF-8"); resp.getWriter().write(document.toString()); }

37 Match document = $("html", head(), $("img").attr("src", "/logo.jpg"), $("h1", “Page name"), $("form").attr("method", "post").append( hiddenField(this.bankNum, "bankNum"), hiddenField(this.customerId, "customerId"), $("h2", "Save changes"), $("div", $("input").attr("type", "submit").attr("value", "Store")).attr("name", "update")));

38 Norwegian Power Transmission System Operator

39 Universal repository Universal service Commands and Queries One domain model

40 No Spring – 100 KLOC

41 Single-jar deployment Includes scripts Includes Jetty

42 public class StatnettWebServer { private final org.eclipse.jetty.server.Server server; public ContactWebServer(int port) { server = new Server(port); server.setHandler(new WebAppContext(“…", "/statnett")); } void start() throws Exception { server.start(); } String getUrl() { int port = server.getConnectors()[0].getLocalPort(); return "http://localhost:" + port + "/contacts"; } public static void main(String[] args) throws Exception { StatnettWebServer server = new StatnettWebServer(10080); server.start(); System.out.println(server.getUrl()); }

43 SpareBank1

44 10 web service clients

45 HttpURLConnection JOOX

46 @Override public String getCountryByIp(String ipAddress) throws Exception { Document soapRequest = soapElement("S:Envelope", $("S:Body", wsxElement("wsx:GetGeoIP", $("wsx:IPAddress", ipAddress)))); Document soapResponse endpoint.postRequest(getSOAPAction(), soapRequest); return $(soapResponse).xpath("/Envelope/Body/*").xpath("GetGeoIPResult/CountryName").text(); }

47 public Document postRequest(String soapAction, Document soapRequest) { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.addRequestProperty("SOAPAction", soapAction); connection.addRequestProperty("Content-Type", "text/xml"); $(soapRequest).write(connection.getOutputStream()); int responseCode = connection.getResponseCode(); if (isErrorResponse(responseCode)) { String response = toString(connection.getErrorStream()); String responseContentType = connection.getContentType(); if (responseContentType.startsWith("text/xml")) { return response; } throw new ServiceCommunicationException( "On POST to " + url + ": " + responseCode + " " + connection.getResponseMessage() + ": " + response); } return $(connection.getInputStream()).document(); d}

48 Conclusion:

49 YAGNI

50 Test-driven development High investment in tests Low investment in frameworks

51 Thank you jbr@exilesoft.com http://johannesbrodwall.com http://exilesoft.com http://twitter.com/jhannes


Download ppt "Bare-knuckle web development Odessa Johannes Brodwall, Chief scientist Exilesoft Global."

Similar presentations


Ads by Google