javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen

14 Rettelser og tilføjelser

I dette kapitel finder du rettelser og tilføjelser til den trykte bog (rettelserne er ført ind på http://javabog.dk). Du kan udskrive kapitlet og gemme bagest i din bog.

14.1 Vigtige rettelser til 1. udgave

I afsnit 3.3, Appendiks: Typer af formularfelter, ret (tak til Klaus Elmquist Nielsen):

<input type="hidden">

Skjult felt. Vises for brugeren, men alligevel har en værdi, se afsnit 3.6.2, Skjulte felter i formularer.

Til:

<input type="hidden">

Skjult felt. Vises ikke for brugeren, men har alligevel en værdi, se afsnit 3.6.2, Skjulte felter i formularer.

I log_ind.jsp i afsnit 9.5.3, Login-siden, ret:

<font color="red">
<%
if (login.isLoggetInd()) {

Til:

<font color="red">
<%
login.tjekLogin();
if (login.isLoggetInd()) {

I VekslerBean.java i afsnit 12.2.2, Eksempel: Veksler, ret:

    System.out.println("dollarTilEuro("+dollar+euro+") kaldt!");

Til:

    System.out.println("dollarTilEuro("+dollar+") kaldt!");

En række steder i kapitel 11 og kapitel 12 skal linjen

  public double euroTilDollar(int euro)

i Veksler-klassen rettes til

  public double euroTilDollar(double euro)

side 227, afsnit 11.7, punkt 1 i listen:

XML kræver at alle attributter skal være i "..", hvoraf

<motor hk=100 />

skal være

<motor hk="100" />

14.2 Større tilføjelser til 1. udgave

Afsnit 3.7.6 Sende mere data til klienten løbende og de tre efterfølgende afsnit.

Afsnit 5.8.6 Metadata og afsnit 5.8.7 Eksempel: Webgrænseflade til database.

Kapitel 15 om Java Server Faces.

14.2.1 Sende mere data til klienten løbende

Nogen gange kan en anmodning tage lang tid at fuldføre. Det kan f.eks. være en krævende operation eller et indviklet databaseopslag.

I sådanne tilfælde vil brugeren opleve at siden tager utrolig lang tid at indlæse. Da er det hensigtsmæssigt at sende noget af svaret på anmodningen, f.eks. titel og overskrift på siden, gerne nogle instruktioner eller forbehold for hvordan det efterfølgende resultat (når det kommer) skal læses.

I andre tilfælde kommer der løbende data som klienten skal se efterhånden som de dukker op.

Man tvinger serveren tømme sine interne buffere og sende al data til klienten ved at kalde

  out.flush();

Derved sendes HTTP-hovedet1 og det, der indtil videre er skrevet til out-objektet.


14.2.2 Eksempel: Syvtabellen langsomt

Her er eksemplet Syvtabellen fra afsnit 2.2.1 skrevet sådan at der går et sekund mellem hver linje:

<html>
<head><title>Syvtabellen langsomt</title></head>
<body>
<p>Her er syv-tabellen:<br>

<% 
  for (int i=1; i<=10; i++)
  {
    out.flush();        // tøm interne buffere, sådan at data sendes til klienten
    Thread.sleep(1000); // vent et sekund
%>
    Syv gange <%= i %> er: <%= 7*i %>.<br>
<% 
  } 
%>
</p>
</body>
</html>



14.2.3 Eksempel: Følge med i serverens logfil

Det følgende eksempel følger med i Tomcats logfil (logs/catalina.out) og opdaterer hvert sekund siden med de nyeste oplysninger fra logfilen.

<html>
<head><title>Serverlog</title></head>
<body>
<h1>Webserverens logfil</h1>
Det følgende er det nyeste fra webserverens logfil.<br>
Hvert sekund opdateres siden hvis der kommer mere i loggen, i de næste 10 minutter.
<pre>
<%
  String filnavn = "logs/catalina.out"; // sti til Tomcats logfil
  long glFilLgd = 0;                    // hvor mange byte filen fylder
  byte[] buf = null;                    // en databuffer
  java.io.RandomAccessFile fil = null;  // ... og selve filen
 
  for (int i=0; i<600; i++)             // gennemløb 60 sekunder * 10 minutter
  try {
    Thread.sleep(1000); // vent et sekund

    fil = new java.io.RandomAccessFile(filnavn,"r");   // åbn filen
    
    if (glFilLgd < fil.length())                       // har længden ændret sig?
    {
      if (glFilLgd==0) glFilLgd = fil.length()-1500;  // læs sidste 1500 tegn
      int bufLgd = (int) (fil.length() - glFilLgd);      
      if (buf==null || bufLgd > buf.length) buf = new byte[bufLgd];
      fil.seek(glFilLgd);
      fil.read(buf,0,bufLgd);
      String tekst = new String(buf,0,bufLgd);
      out.println("---- lgd="+fil.length()+" tid="+new java.util.Date()+" ----");
      out.write(tekst);
      out.flush();     // tøm interne buffere, sådan at data sendes til klienten
      glFilLgd = fil.length();
    }
  } finally {
    fil.close();
  }
%>
</pre>
Slut. <br>
Vil du se mere af logfilen må du genindlæse siden.
</body>
</html>

Bemærk at det kan være en sikkerhedsrisiko at kunne følge med serverloggen (her kan ubetænksomme programmører f.eks. komme til at logge brugernavne og adgangskoder som andre helst ikke skal have adgang til).


14.2.4 Metadata

xxx tekst ind

14.2.5 Eksempel: Webgrænseflade til database

Under udviklingen af en webapplikation, der bruger en database, kan det være rart med en webbaseret grænseflade til databasen som man kan skrive SQL-kommandoer ned i eller lave forespørgsler med.


<%@ page language="java" import="java.sql.*" %>
<html>
<head><title>Webgrænseflade til database</title></head>
<body>

<h1>SQL-grænseflade til databasen</h1>
Herunder kan du skrive SQL-kommandoer. Adskil kommandoer med ;
<form method="post">
<textarea name="sql" rows="8" cols="70">SELECT * FROM kunder
</textarea>
<input type="submit" name="udf" value="Udfør SQL!">
</form>

<%
  // Se om der kommer nogle SQL-kommander der skal behandles
  String sql = request.getParameter("sql");
  Connection con = null;
  Statement stmt = null;
  if (sql != null) {
    Class.forName("com.mysql.jdbc.Driver");
    con = DriverManager.getConnection("jdbc:mysql:///test");
    stmt = con.createStatement();
    String[] kommandoer = sql.split(";"); // opdel i kommandoer efter skilletegn ;
    for (int k=0; k<kommandoer.length; k++) try {
      String kom = kommandoer[k].trim();
      if (kom.length()==0) continue; // videre til næste linje
      out.println("<hr>Udfører '"+kom+"':<br>");
      if (kom.toUpperCase().startsWith("SELECT")) {
        ResultSet rs = stmt.executeQuery(kom);
        ResultSetMetaData rsmd = rs.getMetaData();
        int antalKolonner = rsmd.getColumnCount();

        out.println("<table border='2'><tr>");
        for (int i=1; i<=antalKolonner; i++) 
          out.println("<th>"+rsmd.getColumnName(i)+"</th>");
        out.println("</tr>");
      
        // udskriv cellerne i hver række
        while (rs.next())
        {
          out.println("<tr>");
          for (int i=1; i<=antalKolonner; i++) 
            out.println("<td>"+rs.getString(i)+"</td>");
          out.println("</tr>");
        }
        out.println("</table>");
        rs.close();
      } else {
        int ret = stmt.executeUpdate(kom);
        out.println("Returkode: "+ret);
      }
    } catch (Exception e) {
      out.println("Der skete en fejl: "+e);
      e.printStackTrace();
    }
    stmt.close();
    con.close();
  }
%>
</body>
</html>


Tillægskapitel til ”Webprogrammering med JSP”

Jacob Nordfalk

http://javabog.dk/

30-03-05

1Og derved kan man så ikke mere foretage omdirigeringer, j.v.f. afsnit 3.7 og afsnit 4.3.

javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen
http://javabog.dk/ - Webprogrammering med Java Server Pages af Jacob Nordfalk.
Licens og kopiering under Åben Dokumentlicens (ÅDL) hvor intet andet er nævnt (72% af værket).

Ønsker du at se de sidste 28% af dette værk (275315 tegn) skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.