530 likes | 676 Views
Bare-knuckle web development. XP Days Ukraine Johannes Brodwall, Chief scientist Exilesoft Global. Bare-knuckle philosophy Demonstration of bare-knuckle web in Java Further directions. Part I:. The bare-knuckle philosophy. High impact with low ceremony. Framework light Test-driven
E N D
Bare-knuckle web development XP Days Ukraine Johannes Brodwall, Chief scientist Exilesoft Global
Bare-knuckle philosophy Demonstration of bare-knuckle web in Java Further directions
Framework light Test-driven No calculators
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");
Server server = new Server(0); server.setHandler(newWebAppContext("src/main/webapp", "/contacts")); server.start(); int port = server.getConnectors()[0].getLocalPort(); String url = "http://localhost:" + port + "/contacts";
<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>
@Test publicvoidshouldShowAddForm() throws Exception { ContactServlet servlet = newContactServlet(); HttpServletRequestreq = mock(HttpServletRequest.class); HttpServletResponseresp = mock(HttpServletResponse.class); StringWriter html = newStringWriter(); when(resp.getWriter()).thenReturn(newPrintWriter(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'"); }
voidshowFindPage(String q, PrintWriter writer) { Document doc = Xml.read("contact/index.html"); doc.selectFirst("[name=nameQuery]").val(nameQuery); Element contactsEl = doc.select("#contacts"); Element template = contactsEl.select(".contact"); contactsEl.clear(); for (Contact contact : contactRepository.find(q)) { contactsEl.add(template.copy().text(contact.print())); } doc.write(writer); }
[TestMethod] publicvoidShouldFindSavedContacts() { var server = newWebServer(); server.Start("http://localhost:12380/"); varurl = "http://localhost:12380"; var browser = newSimpleBrowser.WebDriver.SimpleBrowserDriver(); browser.Url = url + "/contacts"; browser.FindElement(By.LinkText("Add contact")).Click(); browser.FindElement(By.Name("fullName")).SendKeys("Darth Vader"); browser.FindElement(By.Name("phoneNumber")).SendKeys("555-33274-7827"); browser.FindElement(By.Name("saveContact")).Click(); browser.FindElement(By.LinkText("Find contact")).Click(); browser.FindElement(By.Name("nameQuery")).SendKeys("vader"); browser.FindElement(By.Name("nameQuery")).Submit(); browser.FindElement(By.Id("contacts")).Text.Should() .Contain("555-33274-7827"); }
publicclassWebServer { publicvoid Start(stringbaseAddress) { varconfig = newHttpSelfHostConfiguration(baseAddress); config.Routes.MapHttpRoute("web Default", "{controller}/{id}",new{ id = RouteParameter.Optional }); using (var server = newHttpSelfHostServer(config)) { server.OpenAsync().Wait(); Console.WriteLine("Press Enter to quit."); Console.ReadLine(); } } }
Controllers: Create a view Retrieve model from repo Set model on view Render view
@Override publicvoidrender(HttpServletResponseresp) throwsIOException { 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()); }
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")));
Universal repository Universal service Commands and Queries One domain model
Single-jar deployment Includes scripts Includes Jetty
publicclassStatnettWebServer { privatefinalorg.eclipse.jetty.server.Serverserver; publicContactWebServer(int port) { server = new Server(port); server.setHandler(newWebAppContext(“…", "/statnett")); } void start() throws Exception { server.start(); } String getUrl() { int port = server.getConnectors()[0].getLocalPort(); return"http://localhost:" + port + "/contacts"; } publicstaticvoid main(String[] args) throws Exception { StatnettWebServerserver = newStatnettWebServer(10080); server.start(); System.out.println(server.getUrl()); } }
HttpURLConnection JOOX
@Override public String getCountryByIp(String ipAddress) throws Exception { Document soapRequest = soapElement("S:Envelope", $("S:Body", wsxElement("wsx:GetGeoIP", $("wsx:IPAddress", ipAddress)))); Document soapResponseendpoint.postRequest(getSOAPAction(), soapRequest); return$(soapResponse).xpath("/Envelope/Body/*") .xpath("GetGeoIPResult/CountryName").text(); }
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()); intresponseCode = connection.getResponseCode(); if (isErrorResponse(responseCode)) { String response = toString(connection.getErrorStream()); String responseContentType = connection.getContentType(); if (responseContentType.startsWith("text/xml")) { return response; } thrownewServiceCommunicationException( "On POST to " + url + ": " + responseCode + " " + connection.getResponseMessage() + ": " + response); } return$(connection.getInputStream()).document(); d}