Avatar billede thundergod Nybegynder
01. oktober 2003 - 11:20 Der er 27 kommentarer og
1 løsning

Anvendelse af JavaBeans i JSP og Servlets

Hej Eksperter,

Jeg har et problem med anvendelse af Beans i JSP og Servlets.
Problemet er at jeg gerne vil have adgang til en bønne i min Servlet. Bønnen er lagt i en JSP side.
Mit setup er som følger:
Jeg har en PersonBean med attributten(sample) og toString().
Browseren får vist FormJSP som viser en form der har:
action="/beanServlet".
Servletten skal nu gå ind og hente bønnen ned og lægge det ind i et objekt der så kan bruges i alm. java kode i Servletten. Problemet er at når jeg prøver at anvende objektet får jeg NullPointerException..
Jeg har prøvet at videresende fra Servletten til en anden JSP side, og der anvende bønnen.
Det virker fint.. Og jeg kan i den anden JSP tage data ud der tidligere er sat..
Det jeg efterlyser er: Kort kodeeksempel med hvordan Servletten skal hente bønnen.. Evt. med ændringer til JSP siden, hvis jeg har skrevet noget forkert der.

-----------------Kode: personFormJSP.jsp----------------
<%@ page errorPage="personFormJSP_error.jsp" %>
<html>
<head>
<title>
personFormJSP
</title>
</head>
<jsp:useBean id="personBean" scope="request" class="jspservletjspwithbean.PersonBean" />
<jsp:setProperty name="personBean" property="*" />
<form action="/persongemmerservlet" method="post">
<br>Enter new value  :  <input name="sample"><br>
<input type="submit" name="Submit" value="Submit">
<input type="reset" value="Reset">
<br>
Value of personBean.sample is : <jsp:getProperty name="personBean" property="sample" /><br>
<hr><br>
</form>
</body>
</html>

----------Kode: personGemmerServlet------------------
package jspservletjspwithbean;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

public class personGemmerServlet extends HttpServlet {
  private static final String CONTENT_TYPE = "text/html";
  private static final String DOC_TYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" +
      "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
  public void init() throws ServletException {}
 
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost( request, response );
  }

  //Process the HTTP Post request
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    PersonBean pb = null; 
    try {
      pb = (PersonBean) request.getAttribute("personBean");
      //Virker ikke: System.out.println( pb.toString() );
      getServletConfig().getServletContext().
          getRequestDispatcher("/personDisplayJSP.jsp").
          forward(request, response);
    } catch (Exception ex) {
      System.err.println("Fejl i personGemmerServlet: " + ex.getMessage());
      ex.printStackTrace(System.err);
    }
  }
  //Clean up resources
  public void destroy() {}
}

I må bære over med at mit indlæg blev lidt langt..
vh Thundergod
Avatar billede arne_v Ekspert
01. oktober 2003 - 11:28 #1
Put din bønne i sessionen i.s.f. i requesten - det er nemlig 2 forskellige
requests.
Avatar billede arne_v Ekspert
01. oktober 2003 - 11:31 #2
scope="session" i JSP
Avatar billede arne_v Ekspert
01. oktober 2003 - 11:32 #3
request.getSession().getAttribute i servlet.
Avatar billede thundergod Nybegynder
01. oktober 2003 - 12:02 #4
Tak for svaret, men det løste desværre ikke problemet.
Når jeg har ændret scope="session" i begge jsp sider,
kan jsp side nummer 2 se bønnen med:
<jsp:getProperty name="personBean" property="sample" />
Men når jeg i Servletten siger:
PersonBean pb = (PersonBean)request.getSession().getAttribute("personBean");
og derefter:
System.out.println( pb.getSample() );
Får jeg udskrevet (i JBuilder) den tekst sample som default er sat til,
selvom jeg i den anden jsp godt kan få den værdi af sample ud som den blev sat til i den første jsp..
Hvad sker der her??

Hvad var det du mente med at der er to request??

vh Thor
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:26 #5
forward laver ikke en ny request, men en form submit er en ny request (og har
derfor et nyt request objekt.
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:28 #6
Du er opmærksom på at:

<jsp:setProperty name="personBean" property="*" />

ikke bliver udført ?
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:30 #7
Du kalder JSP siden.

Felterne har ingen værdier og bønnen for defor ikke sat noget.

JSP siden returnerer form til browser.

Browser submitter og kalder servlet.

Beanen er der men har ikke nogen værdier.
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:30 #8
Hvorfor bruger du iøvrigt ikke bare servlet.getParameter("sample") i
servletten ?
Avatar billede thundergod Nybegynder
01. oktober 2003 - 12:38 #9
OK, jeg tror jeg forstår lidt mere nu.
For i det eksempel som jeg prøvet at implementere stod der i FormJSP:
<jsp:useBean id="personBean" class="pakkenavn.personBean"
  scope="request"/>
<jsp:setProperty name="personBean" property="*" />
<jsp:forward page="/personGemmerServlet" />

og i min version af formJSP, har jeg slettet <jsp:forward...> tagget, da
jeg ikke kunne få vist formen, den forwardede med det samme til servletten.

Kan det løse 'problemet' med to requests??

Du siger at beanen er der men ikke har værdier, hvordan kan det så være at jeg kan få værdierne frem i den anden JSP? Er det fordi der er to requests??
Avatar billede thundergod Nybegynder
01. oktober 2003 - 12:39 #10
hvis jeg i min servlet skriver:
servlet.getParameter("sample")
Får jeg at vide at servlet ikke er et objekt..
Hvis jeg istedet skriver:
get og så ctrl+Space i JBuilder er der en metode der hedder getInitParameter(), men jeg går ikke ud fra at det er det du mener..
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:40 #11
<jsp:setProperty name="personBean" property="*" />

sætter værdier i beanen hvis JSP siden bliver kaldt ved submit
(i modsætning til at være den der laver submit siden).
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:40 #12
<jsp:forward page="/personGemmerServlet" />

er igen en forward og bevarer dermed request objektet.
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:44 #13
Jeg vrøvler.

Jeg mener naturligvis:

request.getParameter("sample")
Avatar billede thundergod Nybegynder
01. oktober 2003 - 12:46 #14
Til kommentaren 12:40:21..
Det vil sige at min struktur skulle være:
HTMLForm->JSPForm->Servlet->DisplayJSP
hvor -HTMLForm er en for der som submit har JSPForm
    -JSPForm har <jsp:setProperty name="personBean" property="*" />
        og forwarder til servlet
    -Servlet arbejder med beanen og forwarder til DisplyJSP
    -DisplayJSP læser fra beanen.
Er det korrekt?
Avatar billede thundergod Nybegynder
01. oktober 2003 - 12:48 #15
Til kommentaren 12:44:31..
Er en Parameter ikke kun hvis den ligger i URL (med method="get")
eller skjult hvis det er med method="post"?
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:50 #16
En parameter er der for alle form felter uanset om du bruger GET eller
POST (din JSP bruger POST).

Det er ligegyldigt om den er skjult eller ej.
Avatar billede thundergod Nybegynder
01. oktober 2003 - 12:51 #17
til kommentaren 12:44:31
Når jeg bruger:
PersonBean pb = (PersonBean) request.getAttribute( "personBean" );
pb.toString();
Får jeg NullPointerException..
Avatar billede arne_v Ekspert
01. oktober 2003 - 12:53 #18
Den klassiske struktur er:

browser send GET for form.jsp
serveren kører form.jsp og sender HTML tilbage til browser
form felter udfyldes i browser
browser submitter med post til ProcessServlet
serveren kører ProcessServlet
ProcessServlet henter felter med request.getParameter og gør et eller andet

eller:

browser send GET for form.jsp
serveren kører form.jsp og sender HTML tilbage til browser
form felter udfyldes i browser
browser submitter med post til process.jsp
serveren kører process.jsp
process.jsp henter felter enten med request-getParameter eller med
at sætte dem i en bean
Avatar billede thundergod Nybegynder
01. oktober 2003 - 13:00 #19
Tak det hjalp for at forstå strukturen..
Det jeg gerne vil have er version 1, med Bean, JSP og Servlet.
Dette fordi jeg gerne vil overholde MVC pattern.
Og til dette er den kombination meget dejlig..:-)
Men Hvordan vil du foreslå at jeg skriver min FormJSP side hvis
jeg gerne vil have at jeg kan putte data ind i en Bean og så
sende den til Servletten, for derefter at kunne arbejde med den?
Avatar billede arne_v Ekspert
01. oktober 2003 - 13:06 #20
Der er ikke rigtigt noget formål med den bean i den første.

Formen udfyldes i browseren.

Beanen lever på serveren.

Det eneste du kan bruge bean til er at lave en smartere version af skjult
felt.

Den JSP side der generer HTML form gemmer noget information
i bean som gemmes i session.

Servlet henter den bean frem af session.

Det virker ligesom et hidden felt og er meget mere sikkert da det
slet ikke kommer ud til browseren.
Avatar billede thundergod Nybegynder
01. oktober 2003 - 13:20 #21
Jeg har et eksempel fra Advanced Java 2 Platform fra Deitel(fig 10.22), der benytter én jsp til at både vise form, og hvis data ikke er sat, så forwarder den..
Er det det jeg skal ud i?
Det den gør der er at have en Bean som den sætter data ind i.
Form submitter til selvsamme side. Hvis data er sat i beanen,
benytter de <jsp:forward page="enandenJSP.jsp" />

Men så er vi jo ude i version 2 af din struktur..
Kunne man tænke sig at man i JSPsiden satte en attribut til session:
session.setAttribute("bean", boennen);
hvorefter man forwarder til en servlet og servletten siger:
session.getAttribute("bean");
?
PS. Du har allere fortjent alle point, men jeg forstår det desværre ikke
helt endnu..
Avatar billede arne_v Ekspert
01. oktober 2003 - 13:26 #22
Det er en mulighed.

Men du behøver ikke at forwarde.

Du kan også bare have 2 JSP sider. Eller du kan have en JSP side med
en if sætning som java kode.

Det giver ikke mening at gemme noget i sessionen i den første side
(medmindre man vil bruge det til skjult information jævnfør tidligere).
Men du kan godt gemme beanen enten i session eller request og forwarde
til en servlet eller en anden JSP side (request er god nok ved forward).

Og i JSP kan man bruge scope="session" / scope="request" i.s.f. den
direkte måde som man er nødt til i servlets.
Avatar billede arne_v Ekspert
01. oktober 2003 - 13:29 #23
Jeg lavede engang denne her lille db.jsp:

<%@ page import="java.sql.*" %>
<%
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection("jdbc:odbc:TestMSAccess");
Statement stmt = con.createStatement();
if(request.getMethod().equals("POST")) {
    int F1 = Integer.parseInt(request.getParameter("F1"));
    String F2 = request.getParameter("F2");
    stmt.executeUpdate("INSERT INTO T1 VALUES (" + F1 + ",'" + F2 + "')");
}
%>
<!doctype html public "-//w3c/dtd HTML 4.01 Transitional//en">
<html>
<head>
<title>T1</title>
</head>
<body>
<h1>T1</h1>
<h2>Show data</h2>
<table border>
<%
ResultSet rs = stmt.executeQuery("SELECT * FROM T1");
while(rs.next()) {
%>
<tr>
<td><%=rs.getInt("F1")%></td>
<td><%=rs.getString("F2")%></td>
</tr>
<%
}
%>
</table>
<h2>Add data</h2>
<form method="post" action="db.jsp">
F1:<input type="text" name="F1" size="10">
<br>
F2:<input type="text" name="F2" size="20">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
Avatar billede arne_v Ekspert
01. oktober 2003 - 13:29 #24
Den submitter til sig selv.
Avatar billede thundergod Nybegynder
01. oktober 2003 - 13:58 #25
Dit eksempel ligner lidt det jeg mener med en if() der kontrollerer om bønnens værider er sat. Men jeg tror at vores løsning bliver som følger:
FormJSP genererer en form der bliver vist i Browser.
Browser siger submit, submit kalder igen FormJSP, men nu med parametre (eller post).
FormJSP kan se at parametre er indtastet og forwarder til servletten.
Servletten modtager request og bruger request.getParameter(..) gentagne
gange for at indlæse data og sette data i en bønnes objekt:
bean.setName(request.getParameter("navn"));
bean.setXxxx(request.getParameter("xxxx"));
osv.
Servlet sørger for persistens med Persistence Framework.
Servlet forwarder til en ny ShowConfirmationJSP.
ShowConfirmationJSP kan nu sige at data er indsat i DB..

Lyder det fornuftigere?
Avatar billede arne_v Ekspert
01. oktober 2003 - 14:03 #26
Jeg kan ikke helt se hvorfor du ikke lige så godt kunne submitte
direkte til servlet.

Men bortset fra det er det en meget typisk måde at gøre tingene på.
Avatar billede thundergod Nybegynder
01. oktober 2003 - 14:15 #27
Det har du ret i..
Jeg prøver lige. Men det tager et stykke tid..
Tak for hjælpen og du har fortjent alle point..
Jeg laver et nyt spørgsmål hvis der er mere..
vh Thor
Avatar billede thundergod Nybegynder
01. oktober 2003 - 16:53 #28
OK Arne,
Nu virker det..Servlet kan læse Beanen der er brugt i JSP
Det jeg gjorde var følgende:
JSP bruger <jsp:forward page="/servletten"/>
Servlets post metode bruger så:
request.getSession().getAttribute("beanNavn");
Og så virkede det, nu kan jeg hente beanen ned uden at få NullPointer eller JasperException.
Trikket ligger i at sålænge vi kun forwarder, beholder vi det samme 'request'.
Så snart vi siger: response.sendRedirect("url"); eller i form sætter: action="url", så får vi et nyt request objekt og deri ligger beanen selvfølgelig ikke!

Tak for hjælpen, selvom det tog lang tid før den fes ind..:)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester