Top Banner
Bare-knuckle web development Odessa Johannes Brodwall, Chief scientist Exilesoft Global
51

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

Dec 30, 2015

Download

Documents

Harvey Bates
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Bare-knuckle web development Odessa Johannes Brodwall, Chief scientist Exilesoft Global.

Bare-knuckle web development

OdessaJohannes Brodwall, Chief scientist

Exilesoft Global

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

• Bare-knuckle philosophy• Demonstration of bare-

knuckle web in Java• Further directions

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

Part I:

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

The bare-knuckle philosophy

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

• High impact/low ceremony• Framework light

• Test-driven

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

High impact with low ceremony

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

Java web: Servlets, WebDriver, Jetty,

Mockito

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

Java SOAP: JOOX, HttpURLConnection

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

.NET web prototype: WebDriver + HttpListener

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

.NET web work-in-progress:

WebDriver + HttpSelfHostServer

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

Light on framework

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

Frameworks solve 80% of the job…

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

… and makes the rest 10 times as hard

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

“Why did Hibernate suddenly slow down?”

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

“How do I implement a custom SOAP header

with JAX-WS?”

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

“How to do X with Spring”

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

@AutoWire + package scan with 100s of beans

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

Test-driven

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

No more architecture than what’s needed

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

Fast feedback cycle – also in the future

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

Part II:

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

Demo: Phonebook web app

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

Test driving

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

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");

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

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";

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

<web-app version="2.5“>

<servlet> <servlet-name>contactServlet</servlet-name> <servlet-class> com.exilesoft.bareknuckleweb.ContactServlet </servlet-class></servlet>

<servlet-mapping> <servlet-name>contactServlet</servlet-name> <url-pattern>contact/*</url-pattern></servlet-mapping>

</web-app>

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

public class ContactServlet extends HttpServlet {}

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

@Testpublic 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'");}

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

Refactoring

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

Part III:

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

Further directorions

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

Norwegian agricultural

authority

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

Java web application with an MVC architecture

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

Controllers:• Create a view

• Retrieve model from repo• Set model on view

• Render view

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

View example:

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

@Overridepublic 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());}

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

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")));

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

Norwegian Power Transmission

System Operator

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

Universal repository

Universal service

Commands and Queries

One domain model

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

No Spring – 100 KLOC

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

Single-jar deployment• Includes scripts

• Includes Jetty

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

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()); }}

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

SpareBank1

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

10 web service clients

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

HttpURLConnection

JOOX

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

@Overridepublic 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();}

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

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}

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

Conclusion:

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

YAGNI

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

Test-driven development

High investment in tests

Low investment in frameworks

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

Thank [email protected]

http://johannesbrodwall.com

http://exilesoft.com

http://twitter.com/jhannes