webForumDet fria alternativet

Förslag på servletlösning

3 svar · 630 visningar · startad av jepsO

jepsOMedlem sedan mars 2001484 inlägg
#1

I ett skolprojekt har jag delansvaret för att skapa ett användargränssnittet till ett tågbokningssystem. Inom gruppen bestämde vi oss för att försöka skapa en webbaserad lösning. Vår del av slutprodukten ska sedan kommunicera med en databas och en uppsättning algoritmer som hittar resvägar, allt skrivet i Java.

Därför tänkte vi att en JSP-/Servlet-baserad lösning för användargränssnittet borde vara en bra idé. Tyvärr vet varken jag eller de andra riktigt vad JSP/Servlets innebär, annat än att det borde vara lösningen på våra problem.

Rätta mig om jag har fel nu:
Om alla gruppers komponenter ska ligga på en och samma server, kan vi då skriva en servlet som dels kommunicerar med de andra komponenterna, men även genererar webbsidor till gränssnittet och tar hand om formulärdata, etc.?

Ni får gärna leda mig på rätt spår med konceptuella förklaringar, exempel, användbara resurser, etc.

Stort tack på förhand!

LimeMedlem sedan sep. 2001961 inlägg
#2

Jo, ni är inne på rätt spår. Servlet/JSP-tekniken bygger på det designmönster som kallas för Model-View-Controller eller MVC. I den modellen är Model era olika "komponenter" eller operationer som jag skulle föredra att kalla det. Det är alltså de som innehåller själva logiken.

View representeras av JSP-sidorna och skall visa upp resultatet. Försök att se till att de innehåller så lite logik som möjligt. Den logik som skall finnas i jsp-sidorna skall BARA vara sådan som behövs för att få rätt utseende baserat på vad som kommit som resultat.

Controller i det här fallet är en, eller flera, servlets som kopplar jsp-sidor med en viss operation.

När vi bygger den här typen av system så använder vi oss ofta av ett servlet som vi kallar för dispatcher. Denna får ett anrop från någon och baserat på frågesträngen (query string) så väljer den att skicka vidare frågan till en operation.

En typisk sida är en sida med ett formulär där formuläret postas till dispatchern. I formuläret finns ett gömt fält med namnet "operation" och sedan "koden" för operationen.

Antag att vi har en sida där jag frågar efter kunduppgifter baserat på ett kundnummer. Sidan ser då ut såhär:

<%@ page language="java" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title>Get Customer Information</title>
</head>
<body bgcolor="#FFFFFF">
<h1>Get Customer Information</h1>
<form name='getCustomerForm' action='/dispatcher'>
<input type='hidden' name='operation' value='getCustomer'/>
Customer number: <input name='customerNumber' size='10' /><br>
<input type='submit'>Fetch</input>
</form>
</body>
</html>

Dispatcher-servleten ser ut något såhär:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * Created on Nov 21, 2005
 * (c) Lime on educational purposes.
 */

/**
 * @author lime
 *
 * Servlet that dispatch calls to the right operation.
 */
public class Dispatcher extends HttpServlet
{

    private static Map controllerMap = new HashMap();

    static
    {
        // Lägg till alla era operationer här.
        addOperation(new GetCustomerInfoOperation());
    }

    public static void addOperation(Operation operation)
    {
        controllerMap.put(operation.getName(),operation);
    }
 
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException
    {
        String operationKey = request.getParameter("operation");
        Operation operation = (Operation) controllerMap.get(operationKey);
        if(operation != null)
        {
            operation.loadProperties(request);
            if(operation.execute())
            {
                Result result = operation.getResult();
                request.getSession().setAttribute("result", result);
                // OBS!!! Efter denna får man inte göra NÅGOT ALLS!!!
                response.sendRedirect(operation.getViewUrl());
                return;
            }
            else
            {
                response.sendRedirect(operation.getErrorUrl());
                return;
            }
        }
    }
}

Dispatchern använder sig av Operation som är en abstrakt klass som används som basklass för alla operationer. Den ser ut såhär:


import java.util.HashMap;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

/**
 * @author lime
 * 
 * Base class for all operations in our system.
 */
public abstract class Operation
{
    public static String name = ""; 
    
    HashMap properties = new HashMap();
  
    public Operation()
    {
        init();
        if(name.trim().length() == 0)
            System.out.println("Operation name not set");        
    }
    
    // Loads the properties into the properties
    public void loadProperties(HttpServletRequest request)
    {
        Iterator keyIterator = properties.keySet().iterator();
        String value;
        while (keyIterator.hasNext())
        {
            String key = (String) keyIterator.next();
            value = request.getParameter(key);
            properties.put(key, value);
        }
    }
    
    protected abstract void init();
    
    public abstract boolean execute();
    
    public abstract Result getResult();
    
    public abstract String getViewUrl();
   
    public abstract String getErrorUrl();
    
    public abstract String getName();
}

Min implementation av operationen GetCustomerInfo ser ut såhär:

public class GetCustomerInfoOperation extends Operation
{

    // Keys
    public static String CUSTOMER_NUMBER ="customerNumber";
    
    // Result
    private Result result;
    
    protected void init()
    {
        // lägg till alla Keys i HashMap:en
        properties.put(CUSTOMER_NUMBER, "");
        
        // Sätt namnet på operationen
        name = "getCustomer";
       
    }

    public boolean execute()
    {
        boolean result = false;
        
        // TODO: Slå upp kunden i databasen och skapa Result-objektet.
        // Hur ni gör det får ni fundera på själva.
        
        // Returnera true om det finns ett result-object och false om det inte gör det...
        return result;
    }

    public Result getResult()
    {
        return result;
    }

    public String getViewUrl()
    {
        
        return "/customer/showCustomerInfo.jsp";
    }

    public String getErrorUrl()
    {
       
        return "/customer/customerNotFound.jsp";
    }

    public String getName()
    {
     
        return name;
    }

}

Om jag får ett resultat så skickar jag allt till showCustomerInfo.jsp som ser ut såhär:

<%@ page language="java" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title>Lomboz JSP</title>
</head>
<body bgcolor="#FFFFFF">
<jsp:useBean id="result" scope="page" class="GetCustomerInfoResult" />

Name: <%=result.getValue(GetCustomerInfoResult.NAME) %></br>
Address: <%=result.getValue(GetCustomerInfoResult.ADDRESS) %></br>
Email: <%=result.getValue(GetCustomerInfoResult.EMAIL) %></br>
</body>
</html>

Hur jag specificerat och implementerat Result och GetCustomerInfoResult får ni fundera ut själva... ;-)

jepsOMedlem sedan mars 2001484 inlägg
#3

Fantastiskt svar! Tack! :bire

LimeMedlem sedan sep. 2001961 inlägg
#4

Tänk på att det är ett svar som inte är komplett... det är en början och ett sätt att få er att tänka i rätt banor... resten måste ni göra själva.

Jag håller aldeles för många kurser i java, arkitekturdesign, designpatterns och liknande för att någonsin kunna ge ett rakt svar... ;)

Om ni skall hålla på med JSP-sidor rekommenderar jag att ni även grottar ner er i Jakartas Taglibs (http://jakarta.apache.org/taglibs/index.html) och då främst Standard JSTL och Input. I18n (internationalization, ett I, 18 bokstäver och ett N) kan vara bra också för att få in "rätt" tänk på hur text-resurser bör hanteras...

134 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
131 ms — hämta tråd, inlägg och bilagor (db)