Bare-knuckle web development
description
Transcript of Bare-knuckle web development
![Page 1: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/1.jpg)
Bare-knuckle web development
OdessaJohannes Brodwall, Chief scientist
Exilesoft Global
![Page 2: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/2.jpg)
• Bare-knuckle philosophy• Demonstration of bare-
knuckle web in Java• Further directions
![Page 3: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/3.jpg)
Part I:
![Page 4: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/4.jpg)
The bare-knuckle philosophy
![Page 5: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/5.jpg)
• High impact/low ceremony• Framework light
• Test-driven
![Page 6: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/6.jpg)
High impact with low ceremony
![Page 7: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/7.jpg)
Java web: Servlets, WebDriver, Jetty,
Mockito
![Page 8: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/8.jpg)
Java SOAP: JOOX, HttpURLConnection
![Page 9: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/9.jpg)
.NET web prototype: WebDriver + HttpListener
![Page 10: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/10.jpg)
.NET web work-in-progress:
WebDriver + HttpSelfHostServer
![Page 11: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/11.jpg)
Light on framework
![Page 12: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/12.jpg)
Frameworks solve 80% of the job…
![Page 13: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/13.jpg)
… and makes the rest 10 times as hard
![Page 14: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/14.jpg)
“Why did Hibernate suddenly slow down?”
![Page 15: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/15.jpg)
“How do I implement a custom SOAP header
with JAX-WS?”
![Page 16: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/16.jpg)
“How to do X with Spring”
![Page 17: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/17.jpg)
@AutoWire + package scan with 100s of beans
![Page 18: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/18.jpg)
Test-driven
![Page 19: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/19.jpg)
No more architecture than what’s needed
![Page 20: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/20.jpg)
Fast feedback cycle – also in the future
![Page 21: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/21.jpg)
Part II:
![Page 22: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/22.jpg)
Demo: Phonebook web app
![Page 23: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/23.jpg)
Test driving
![Page 24: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/24.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/25.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/26.jpg)
<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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/27.jpg)
public class ContactServlet extends HttpServlet {}
![Page 28: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/28.jpg)
@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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/29.jpg)
Refactoring
![Page 30: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/30.jpg)
Part III:
![Page 31: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/31.jpg)
Further directorions
![Page 32: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/32.jpg)
Norwegian agricultural
authority
![Page 33: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/33.jpg)
Java web application with an MVC architecture
![Page 34: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/34.jpg)
Controllers:• Create a view
• Retrieve model from repo• Set model on view
• Render view
![Page 35: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/35.jpg)
View example:
![Page 36: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/36.jpg)
@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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/37.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/38.jpg)
Norwegian Power Transmission
System Operator
![Page 39: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/39.jpg)
Universal repository
Universal service
Commands and Queries
One domain model
![Page 40: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/40.jpg)
No Spring – 100 KLOC
![Page 41: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/41.jpg)
Single-jar deployment• Includes scripts
• Includes Jetty
![Page 42: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/42.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/43.jpg)
SpareBank1
![Page 44: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/44.jpg)
10 web service clients
![Page 45: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/45.jpg)
HttpURLConnection
JOOX
![Page 46: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/46.jpg)
@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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/47.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/48.jpg)
Conclusion:
![Page 49: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/49.jpg)
YAGNI
![Page 50: Bare-knuckle web development](https://reader035.fdocuments.in/reader035/viewer/2022062500/56815a43550346895dc77a45/html5/thumbnails/50.jpg)
Test-driven development
High investment in tests
Low investment in frameworks