Archiv für die Kategorie ‘Allgemeines’

Javascript im href von HTML-Links

Donnerstag, 22. Juli 2010

Wer Probleme damit hat, browserkompatibel auf clicks bei Links zu reagieren, kann dies mit Hilfe des Schlüsselwortes ‘javascript:’ zu Beginn des href-Attributwertes verwirklichen.

Bsp:

<a href="javascript:myFunction();">Ein Link</a>

Angenommen, die Funktion myFunction() sieht nun beispielsweise so aus:

function myFunction() {
alert("Hallo!");
return false;
}

Dann wird die Seite, die den Link beinhaltet, gelöscht und eine neue Seite angezeigt, auf der lediglich das Wort ‘false’ steht. Das liegt daran, dass das Ergebnis des Javascripts in eine neue Seite gerendert wird.

Wichtig ist also, dass der Rückgabewert von myFunction undefined ist, wenn man möchte, dass die ursprüngliche Seite erhalten bleibt.


Christian Borkowski


PostgresSQL String Konstanten / Dateien namens “con.xyz”

Montag, 05. Juli 2010

Mein Ziel war es, korrupte javascript-RegEx Ausdrücke durch neue Ausdrücke zu ersetzen. Das Problem dabei waren die Zeichen, die ein Escaping benötigen, um den String(character varying) in eine Postgres DB einfügen zu können. Bei recht komplexen Ausdrücken eine umständliche Arbeit, die Zeichen einzeln zu “escapen”. Das ganze kann man sich aber folgendermaßen ersparen:

UPDATE testtabelle
SET textfeld = $stringconstant$Text mit vielen /^'\" $$stringconstant$
WHERE id = 4711;

Das ganze nennt sich “Dollar-Quoted String Constants”. Der String wird also zwischen zwei voranführenden und zwei endenden Dollarzeichen verpackt: $$ SomeCharacters/\^’#” $$ . Zwischen den Dollarzeichen kann, wie im obigen Beispiel, ein Tagname angegeben werden, um so z.B. auch verschachtelte Strukturen zu ermöglichen.

$outerTag$
someText $innerTag$ otherText $innerTag$
$outerTag$

Ein ganz anderes Thema…

Bei dem Versuch eine csv-Datei aus Java heraus anzulegen, flog eine Exception, nach ein bischen Verzweiflung und “googeln” kam heraus, dass der Name der Datei con.csv das Problem verursachte.
WindowsXP verbietet das Anlegen jeglicher Dateien mit Namen “con” gefolgt von einem Punkt oder einem Leerzeichen. Ärgerlich aber nicht umgehbar, angeblich ein Überbleibsel aus den alten MS-Dos Zeiten.


Sven Seiler


Zeitmessung mit Spring AOP

Donnerstag, 24. Juni 2010

Trifft man bei der Entwicklung einer Anwendung auf Performanceprobleme, reicht es meist aus, die verantwortlichen Codebereiche aufzuspüren, um dann den Fehler/das Problem zu beheben. Jedoch gestaltet sich das Auffinden der betroffenen Codestellen meist als schwierig oder langwierig. In jede verdächtige Methode Log-Ausgaben mit der Zeitmessung zu schreiben, wäre unsauber. Mit Spring ist die einfachste Lösung, einen Interceptor zu konfigurieren, der die Methodenaufrufe unterbricht und die Zeitmessung ins Log schreibt.

Als erstes definieren wir einen Advice (Interceptor-Bean), die Implementierung bringt Spring schon mit.

<bean id="timingLogger" 
class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor" />

Als zweiten Schritt können wir mit der AOP Konfiguration festlegen, welche Methodenaufrufe protokolliert werden sollen, damit die Log-Datei übersichtlich bleibt. Folgend zum Beispiel alle public-Methoden der Spring-Beans im Paket service und allen Unterpaketen:

<aop:config>
   <aop:pointcut id="services" expression="execution(* de.myApp.service..*.*(..))" />
   <aop:advisor advice-ref="timingLogger" pointcut-ref="services" />
</aop:config>

Für das Definieren der korrekten pointcut-expression hilft die ausführliche Spring Dokumentation (7.2.3 Declaring a pointcut, Version 3).
Damit das Ergebnis in den Logs auftaucht, sollte für diesen Interceptor der Log-Level auf TRACE stehen:

log4j.logger.org.springframework.aop.interceptor.PerformanceMonitorInterceptor=TRACE

Die Ausgabe sieht dann zum Beispiel so aus:

2010-06-24 09:06:53,109 TRACE PerformanceMonitorInterceptor:64 - StopWatch 'de.myApp.service.MyService.methodName': running time (millis) = 1813

Für eine erste Analyse ist diesen Vorgehen hilfreich, will man jedoch aggregierte Werte über einen Zeitraum bekommen, bietet sich zum Beispiel Perf4J an. Mit diesem Tool lassen sich aggregierte Messwerte (Min, Max, Durchschnitt, Anzahl) in eine extra Logdatei schreiben.

Es besteht aber auch die Möglichkeit einer einfachen eigenen Implementierung:

public class TimingLoggingInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        StopWatch sw = new StopWatch();
        sw.start();
        Object returnValue = invocation.proceed();
        sw.stop();
        System.out.println(
            invocation.getClass().getSimpleName() + "#" + 
            invocation.getMethod().getName() + ": " +
            sw.getTotalTimeMillis());
        return returnValue;
    }
}

Nun muss nur noch der Wert der Spring-StopWatch gespeichert werden. Diese eigene Lösung ist besonders interessant, wenn nur unter bestimmten Bedingungen die Werte geloggt werden sollen, zum Beispiel wenn die Laufzeit eine definierte Obergrenze überschreitet.


Jan Kuenstler


Excel-Dateien mit Apache POI bearbeiten

Montag, 07. Juni 2010

Ein für viele Entwickler eher unerfreuliches Thema ist die Arbeit mit Microsoft Office Dateien in Java. Insbesondere Excel-Dateien werden von Fachabteilungen gerne als Ein- oder Ausgabeformat gesehen. Oft kann man sich dann auf einen Import bzw. Export via csv einigen. Wenn dies nicht möglich ist, lohnt es sich, einen Blick auf Apache POI zu werfen. Das Projekt hat sich der MS-Office-Thematik angenommen und gliedert sich in mehrere Subprojekte, die sich jeweils mit den einzelnen Office-Formaten beschäftigen. Viele dieser Subprojekte sind noch in einem sehr frühen Stadium und daher mit Vorsicht einzusetzen. Als ziemlich ausgereift kann man hingegen die Subprojekte HSSF und XSSF bezeichnen. HSSF liefert Unterstützung für das alte Excel-Dateinformat, das bis einschließlich Excel 2003 eingesetzt wurde. XSSF dagegen liefert die Unterstützung für das neuere XML-basierte Format, das mit Excel 2007 eingeführt wurde. Im folgenden soll anhand eines kurzen Beispiels ein erster Einblick in die Arbeit mit HSSF/XSSF gegeben werden. Dabei wird die Version 3.6 von POI eingesetzt.

HSSF und XSSF arbeiten mit einer Reihe von gemeinsamen Interfaces, die die Bestandteile einer Excel-Datei repräsentieren. Die folgenden Interfaces kommen in unserem Beispiel zum Einsatz:

  • Workbook repräsentiert eine Excel-Datei
  • Sheet repräsentiert eine einzelne Tabelle
  • Row repräsentiert eine einzelne Tabellenzeile
  • Column repräsentiert eine einzelne Tabellenspalte
  • Cell repräsentiert eine einzelne Tabellenzelle

Um nun eine einfache Excel-Tabelle zu erstellen und in einer xls-Datei zu speichern gehen wir wie folgt vor:

Workbook workbook;
File outputFile;
// wir wollen eine Excel 97 xls-Datei erzeugen, verwenden also HSSF
workbook = new HSSFWorkbook();
outputFile = new File("c:/Dateiname.xls");
 
// bei der Erzeugung der Daten arbeiten wir nur noch mit den Interfaces und damit
// formatunabhängig:
Sheet sheet = workbook.createSheet("Einkäufe");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Ware");
cell = row.createCell(1);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Preis");
row = sheet.createRow(1);
cell = row.createCell(0);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Brot");
cell = row.createCell(1);
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(1.19);
row = sheet.createRow(2);
cell = row.createCell(0);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Butter");
cell = row.createCell(1);
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(0.89);
row = sheet.createRow(3);
cell = row.createCell(0);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Summe");
cell = row.createCell(1);
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
// wir können mit setCellFormula auch Formeln für einzelne Zellen angeben
cell.setCellFormula("SUM(B2:B3)");
 
// Schreiben der Datei
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
workbook.write(fileOutputStream);
fileOutputStream.close();

Um stattdessen eine xslx-Datei (Excel 2007) zu erzeugen müssen wir im obigen Beispiel lediglich die Zeilen

workbook = new HSSFWorkbook();
outputFile = new File("c:/Dateiname.xls");

durch

workbook = new XSSFWorkbook();
outputFile = new File("c:/Dateiname.xlsx");

ersetzen. Der restliche Code bleibt unverändert. Ziemlich einfach, oder?

Ich wünsche viel Spaß beim Ausprobieren!


Malte Wulf