Oct 19

Während ich mich im ersten Teil in meiner kleinen Serie über HTTP Clients mit Pear beschäftigt habe, will ich nun im 2. Teil mein Augenmerk auf das Zend Framework richten.

Auch hier benötigt man 2 Packages zur Erledigung der Aufgabe (s. Teil 1). Das Package Zend_Http ist wie das Pear Package Http_Request2 zur reinen HTTP Kommunikation geeignet.
Mit Zend_Dom kann man das empfangene HTML zerlegen.

Ein Weg zur Lösung der Aufgabe könnte so aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
require_once 'Zend/Http/Client.php';
require_once 'Zend/Http/Response.php';
require_once 'Zend/Dom/Query.php';
 
$url='http://www.google.de';
 
$client = new Zend_Http_Client($url, array(
    'maxredirects' => 0,
    'timeout'      => 30));
 
try {
   $response = $client->request('GET');
 
   if (200 == $response->getStatus()) {
 
      $dom = new Zend_Dom_Query($response->getBody());
      $forms = $dom->query('form');
 
      $form=$forms->current();
      $action=$form->getAttribute('action');
 
      $client = new Zend_Http_Client($url.$action, array(
          'maxredirects' => 0,
          'timeout'      => 30));
      $client->setParameterGet('q', 'http client examples');
      $response = $client->request('GET');
 
      $dom = new Zend_Dom_Query($response->getBody());
 
      foreach ($dom->query('a.l') as $link) {
         if ($link->hasAttribute('href')) {
            $href=$link->getAttribute('href');
            $linkText=$link->textContent;
 
            echo "<a href=\"$href\">$linkText</a><br />";
         } 
      }
 
   } else {
        echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
             $response->responseCodeAsText();
    }
} catch (Zend_Http_Exception $e) {
    echo 'Error: ' . $e->getMessage();
}
?>

Der Code spricht eigentlich für sich, deswegen werde ich ihn an dieser Stelle nicht so detailliert erläutern wie noch im ersten Teil.
Der Unterschied besteht im Parsen des HTML’s. Die Methode query() (Zeilen 18 und 31) liefert nämlich kein Array, sonder ein Objekt der Klasse Zend_Dom_Query_Result zurück. Da diese Klasse die beiden Interface Countable und Iterator implementiert, können die Ergebnisse der Anfrage mit einer foreach Schleife durchlaufen werden. Jeder einzelne Treffer wird über ein Objekt der Klasse DOMElement abgebildet.

Fazit:
Auch Zend bietet mit Zend_Http und Zend_Dom einen guten HTTP Client. Nutzt man in seinem Projekt bereits andere Klassen aus dem Zend Framework ist dieser Lösungsansatz empfehlenswert.

Ausblick:
In Teil 3 verlasse ich die PHP Welt und stelle mit HttpUnit einen sehr komfortablen und funktionsreichen HTTP Client für Java vor.

Ähnliche Artikel:

geschrieben von gklinkmann \\ tags: , ,

Oct 11

Die Woche vor dem Urlaub ist immer ein bisschen stressig. Von daher gibt es heute nur 2 Links:

Einstieg in Spring Roo RC2
Wer Grails nicht nutzen darf oder will erhält mit Spring Roo einen Code Generator für Webanwendungen, der auf Spring und Java basiert.
Wordpress mit Lucene
Die freie Suchbibliothek hält über ein Plugin Einzug in Wordpress.
Ähnliche Artikel:

geschrieben von gklinkmann \\ tags: , , , ,

Oct 03

Über die Woche verteilt, gibt es immer wieder interessante Artikel im Netz für mich, die mir ein Lesezeichen bei delicious.com wert sind. Einige sind der Anstoß für einen Beitrag in meinem eigenen Blog, die meisten aber gesammeltes Wissen (wir alle sind Jäger und Sammler), das zum Abruf bereit steht.

Diese Woche haben es folgende Artikel in meine Linkliste geschafft:

Quellensammlung: Die besten CSS- und Design-Galerien
Ein gutes Layout ist ebenso wichtig, wie die Technik dahinter. Hier sind ein paar Beispiele.
ImageFlow von Finn Rudolph
Eine sehr schöne Umsetzung des Apple Cover Flow fürs Web.
10 Useful Usability Findings and Guidelines
Das Smashing Magazine hat ein paar Ergebnisse seiner Studie zur Usability von Websites herausgegeben – sehr interessant.
Stylish Charts Using CSS jQuery and PHP
Bisher habe ich Diagramme immer als Bild on the fly erstellt. Die Lösung mit PHP und jquery ist aber auch ein interessanter Ansatz.
Browser mit PHP fernsteuern
Nils Langner vom phphatesme Blog erklärt, wie man mit selenium und PHP den Browser fernsteuern kann. Automatisierte Funktionstests stehen schon sehr lange auf der Themenliste für meinen Blog. Es wird Zeit für einen Beitrag.
Grails 1.2: Spring 3, Uri Rewriting und mehr
Sehr guter Artikel zum kommenden Grails 1.2 Release.
Ähnliche Artikel:

geschrieben von gklinkmann \\ tags: , , , , , ,

Oct 01
spring-icon

Seit vorgestern steht der erste Release Candidate vom Spring Framework zum Download bereit.
In dieser Version werden erstmalig der JSR-303 (Bean Validation) und JSR-330 (Dependency Injection in Java) unterstützt. Besonders auf die Umsetzung der Bean Validation war ich gespannt, denn dadurch kann man über Annotations seine Beans mit Constraints versehen.

In einer Spring basierten Web Anwendung könnte man die Bean Validation wie folgt nutzen.

1. annotieren der Bean

1
2
3
4
5
6
7
public class Event {
   int id;
 
   @NotNull
   @Size(min=1,max=50)
   String description;
...

Durch die zwei Annotations (in validation-api-1.0.CR3.jar enthalten) wird festgelegt, dass der Wert für das Attribut description nicht null sein darf und minimum 1 Zeichen aber maximal 50 Zeichen enthalten muss.

2. validieren der Bean innerhalb des Controllers

Zur Validierung benötigt man eine Implementierung des JSR-303, wie z.B. den Hibernate Validator (momentan in Version 4.0.0 CR1). Der hat allerdings eine Menge Abhängigkeiten und muss erst über Maven kompiliert werden.
Hat man diese Hürde genommen (und hat die daraus resultierende Jar Datei in sein Projekt eingebunden), benötigt man noch folgende Bibliotheken um keine Runtime Fehler zu produzieren:

  • validation-api-1.0.CR3.jar
  • slf4j-api-1.5.6.jar
  • slf4j-log4j12-1.5.6.jar
  • log4j-1.2.14.jar
  • commons-logging-1.0.4.jar (benötigt man nicht unbedingt, wurde aber im Beispiel verwendet)

diese liegen dann aber sowieso im lokalen Maven Repository vor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RequestMapping(value="/event/save", method=RequestMethod.POST)
public String save(Event event,BindingResult bindingResult, Model model) {
   LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
   validator.setProviderClass(HibernateValidationProvider.class);
   validator.afterPropertiesSet();
 
   validator.validate(event,bindingResult);
 
   if (!bindingResult.hasErrors()) {
      // save ...
      model.addAttribute("message", "update successfully");         
   } else {
      for (FieldError e : bindingResult.getFieldErrors()) {
         log.warn(e.getField()+": "+e.getDefaultMessage());            
      }
      model.addAttribute("errors", bindingResult.getFieldErrors());
   }
   model.addAttribute("event", event);
 
   return "update";
}

In den Zeilen 3-5 Wird eine Instanz des Hibernate Validators erzeugt. In Zeile 7 wird dann endlich validiert. Ob bei der Validierung Fehler aufgetreten sind kann man mit der Methode hasErrors() überprüfen (Zeile 9). Zugriff auf alle Fehler (z.B. zum Loggen) erhält man über die Methode getFieldErrors() (Zeile 13-15).
In Zeile 16 werden die Fehler der View übergeben.

3. Ausgabe der Fehler in der View

Zur Ausgabe der Fehler wird die JSP Standard Tag Library verwendet.

1
2
3
4
5
6
7
8
<p>${message}</p>
<c:if test="${!empty errors}">
   <ul>
   <c:forEach var="error" items="${errors}">
      <li>${error.field}: ${error.defaultMessage}</li>         
   </c:forEach>
   </ul>
</c:if>
Ähnliche Artikel:

geschrieben von gklinkmann \\ tags: , ,

Sep 23

Es ist noch gar nicht so lange her, da wurde JavaScript aufgrund seiner Browser Inkombatibilitäten und Sicherheitsbedenken von vielen verteufelt.
Erst mit Ajax (Asynchronous JavaScript and XML) und den darum entstandenen Frameworks (die die Browserinkompatibilitäte abfangen) ist es zum Lieblingskind und “must have” der Webentwicklung geworden.

Doch zwischen den Frameworks gibt es teilweise erhebliche Unterschiede. Das gilt nicht nur für den Funktionsumfang, sondern auch für die Größe und Ausführungsgeschwindigkeit.

Matthias Schütz hat mit seiner Ajax Framework Matrix versucht, die Eigenschaften der Ajax Frameworks in einer Übersicht zusammenzuführen, um sie so besser vergleichen zu können. Dass ist ihm nicht nur gut gelungen, sondern ist auch noch schön anzusehen.
In der Matrix sind auch die Links zu den Frameworks, deren Dokumentation und einigen Beispielen enthalten.

Fazit:
Die Matrix erleichtert wirklich den Vergleich zwischen den einzelnen Ajax Frameworks. Eines leistet die Matrix allerdings nicht.
Eine Entscheidung für eines der Frameworks muss man leider immer noch selbst treffen, nur der Weg dorthin wird unterstützt.

ajax framework matrix

Ähnliche Artikel:

geschrieben von gklinkmann \\ tags: , , , , ,