Tarvitsisin simppelin ohjeen appletin ja servletin väliseen kommunikointiin. RMI ei tapauksessani sovi, vaan ajattelin käyttää serializea kommunikoinnin tekoon.
Ongelma on yksinkertaisesti seuraava: miten saan servletistä haettua applettiin Vector-objektin, joka on servletissä määritelty tyyliin Vector v = new Vector(foo);
Olen erittäin kiitollinen mahdollisista vastauksistanne!
Ongelma on yksinkertaisesti seuraava: miten saan servletistä haettua applettiin Vector-objektin, joka on servletissä määritelty tyyliin Vector v = new Vector(foo);
Olen erittäin kiitollinen mahdollisista vastauksistanne!
Vastaukset 9
Vanhimmat
..ei ole tullut kokeiltua käytännössä, mutta ohessa jonkimmoinen lista tarvittavista asioista:
1. Applet tekee pyynnön servletille serialization-objektista.
2. Servletti muodostaa ns. ObjectOutputStream:n appletin suuntaan.
3. Applet lukee ns. ObjectInputStream:sta olion readObject()-metodilla ja cast:ää siitä toimivan olion.
Tietoturvamielessä suosittelen yhteyden salaamista CipherInputStream/CipherOutputStream:llä ja kolminkertaisella DES:llä (TripleDES).
-Jonttu-
Kiitos vastauksestasi. Itse asiassa mainitsemasi kohta 1 on se varsinainen ongelma, eli kuinka tuo pyyntö käytännössä tehdään. Uskoisin, että minun täytyy muodostaa applettiin socketti joka muodostaa tcp-yhteyden palvelimeen (tähän asti vielä pääsen), mutta mitä tarvitaan serverin päässä? Tarvitsenko kuitenkin RMI:tä?
RMI:ssä ei ole muuta vikaa, muuta kuin se ymmärtääkseni vaatii client-päässä java.policy -tiedoston muokkaamista, mikä taas on mahdotonta clienttien suuresta määrästä johtuen.
Eipä siinä kait muuta tarvita kuin, että sulla on jokin oma protokolla (komento), jonka perusteella tiedät lähettää appletille sen vectorin. Eli servletti avaa perusvirran päälle ObjectOutputStream:n appletin suuntaan. Appletti vastaavasti tietää odottaa inputStream:nä ObjectInputStream:ä ja toimii myös tämän mukaan.
Ohessa jokin vanha tiedostopohjainen kikkailuni, jonka pitäisi hieman muutettuna sopia myös sinun tarpeeseesi (sovella tuosta):
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
public class SerTest {
public static void main(String args[])
{
try {
// Luodaan salausavain
KeyGenerator kg = KeyGenerator.getInstance("DESede");
SecretKey secretKey = kg.generateKey();
// Luodaan salaaja
Cipher desCipher = Cipher.getInstance("DESede");
desCipher.init(Cipher.ENCRYPT_MODE, secretKey);
// luodaan virta
FileOutputStream fos = new FileOutputStream("DESede.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
CipherOutputStream cos = new CipherOutputStream(bos, desCipher);
ObjectOutputStream oos = new ObjectOutputStream(cos);
Command cmdOrig = new Command("testing...");
// kirjoitetaan salattu olio
//ja kirjoitetaan tiedot levylle
oos.writeObject(cmdOrig);
oos.flush();
oos.close();
// vaihdetaan salausmoodia
desCipher.init(Cipher.DECRYPT_MODE, secretKey);
// luodaan virta
FileInputStream fis = new FileInputStream("DESede.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
CipherInputStream cis = new CipherInputStream(bis, desCipher);
ObjectInputStream ois = new ObjectInputStream(cis);
//luetaan salattun olion tiedot
//ja muodostetaan olio
Command cmdRead = (Command)ois.readObject();
ois.close();
System.out.println (cmdRead.getServletCommand());
}
catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}
class Command implements Serializable
{
String servletCommand;
public Command (String servletCommand)
{
this.servletCommand = servletCommand;
}
public String getServletCommand(){
return servletCommand;
}
}
terv. Jonttu
Kiitos antamastasi koodista! En kuitenkaan saanut tästä sitä "punaista lankaa" irti, eli mitä servletissä pitää olla ja mitä appletissa. Ilmeisesti tässä sinun tapauksesssasi kyseessä ei ole lainkaan servletti vaan applikaatio, joka pyörii koneessa ilman tomcattia tai vastaavaa serveriä? Tarvitsisin nimenomaan esimerkiksi pikku servletin, joka osaa serializoida objektin ja välittää sen appletille - ja tietysti myös siihen applettiin tarvittavat rivit.
Miksi käyttää mitään Cipher yms. juttuja, jos niitä ei vaadita (ja sovellus pyörii localhost:ssa). Tekee vaan koodista hitaanpaa ja monimutkasempaa.
Kommunikoinnin servletin kanssa voi tehdä URLConnection-luokalla.
sample,
appletin koodi:
String servletUrl = "servletin url";
URLConnection urlCon = new URL(servletURL).openConnection();
HttpURLConnection httpCon = (HttpURLConnection)urlCon;
httpCon.setDoOutput(true);
httpCon.connect();
ObjectInputStream in = new ObjectInputStream(httpCon.getInputStream());
Vector v = (Vector)in.readObject();
servlet koodi:
Vector v = new Vector();
//lisää jotain vectoriin
ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
out.writeObject(v);
out.flush();
out.close();
Jotain tohon suuntaan.
Kiitos vastauksestasi! Juuri jotain tällaista tarkoitin. Netti on sekalaisia ohjeita pullollaan, mutta toimivaa kokonaisuutta en ole löytänyt. Tässä voisi olla hyvä alku.
Mistä servletti tietää, koska sen pitää ryhtyä serializoimaan objektia eli milloin servletissä olevaa metodia on kutsuttu? Voinko serializoida useampia objekteja, ts. voinko kutsua appletista objekteja tyyliin
Vector v = (Vector) in.readObject(foo1);
Int x = in.readObject(foo2).toInt();
? Jos sulla ois toimiva kokonaisuus, miten yksinkertainen tahansa, voisitko postata sen tänne? Siis sellainen jossa olisi tarvittavat muodostimet ym. runkotarvikkeet mukana. Kiitos etukäteen!
Servletti suorittaa objektin kirjoituksen tulostusviraan aina kun servletin doGet()-metodia kutsutaan. Metodia kutsutaan silloin kun servletille määriteltyä url-osoitetta kutsutaan.
Objektivirrassa voi välittää useita objekteja. Ne pitää vaan lukea samassa järjestyksessä readObject()-metodilla, kun ne on virtaan kirjoitettu writeObject()-metodilla.
Tässä on toimivatn Applet to servlet systeemin koodit. Servletti pitää vaan asentaa johonkin sovelluspalvelimeen (vaikka Tomcat). Esimerkissä servletille välitetään appletilta objekti, jota servletti muokka ja palauttaa muokkauksen jälkeen takaisin appletille. Jos et tarvi objektin kirjotusta servletille niin, ota se vaan karusti pois.
Appletti:
import java.awt.BorderLayout;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import javax.swing.JApplet;
import javax.swing.JLabel;
public class TestiApplet extends JApplet {
public TestiApplet() {
// getRootPane().putClientProperty("defeatSystemEventQueueCheck",Boolean.TRUE);
}
public void init() {
String s = "Tero Ahonen";
JLabel label = new JLabel("Merkkijono ennen servlet-kutsua:" s);
s = this.servletKutsu(s);
JLabel label2 = new JLabel("Merkkijono servlet-kutsun jälkeen:" s);
label.setHorizontalAlignment(JLabel.CENTER);
label2.setHorizontalAlignment(JLabel.CENTER);
getContentPane().add(label, BorderLayout.NORTH);
getContentPane().add(label2, BorderLayout.SOUTH);
}
private String servletKutsu(String s) {
try {
//käytetään samaa servlettiä kuin konsoli ja servlet esimerkissä
String servletOsoite = "http://localhost/webapp/servletti"";
//luodaan yhteys servlettiin
URLConnection urlYhteys = new URL(servletOsoite).openConnection();
HttpURLConnection httpYhteys = (HttpURLConnection) urlYhteys;
httpYhteys.setDoOutput(true);
ObjectOutputStream oos = new ObjectOutputStream(httpYhteys.getOutputStream());
oos.writeObject(s);
oos.close();
httpYhteys.connect();
//luodaan lukija servletin tulostusvirtaan
ObjectInputStream in = new ObjectInputStream(httpYhteys.getInputStream());
return (String) in.readObject();
} catch (Exception e) {
return "virhe:" e.toString();
}
}
}
Servletin koodi:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class KonsoliServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try
{
System.out.println("doGet kutsuttu");
//PrintWriter out = response.getWriter();
//response.setContentType("text/html");
ObjectInputStream in = new ObjectInputStream(request.getInputStream());
String objekti = (String)in.readObject();
ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
objekti = objekti.replace('o', 'O');
System.out.println("objekti servletistä: " objekti);
out.writeObject(objekti);
Integer integer = new Integer(1);
out.writeObject(integer);
out.flush();
out.close();
}
catch (Exception e)
{
System.out.println("KonsoliServlet.doGet(): " e.toString());
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try
{
System.out.println("doPost kutsuttu");
this.doGet(request, response);
}
catch (Exception e)
{
System.out.println("KonsoliServlet.doGet(): " e.toString());
}
}
}
Kiitos paljon, juuri tuollaista esimerkkiä tarkoitin! Kokeilen hommaa heti alkuviikosta päästyäni tomcat-koneeni äärelle.
Täällä palstalla on näköjään todellisia Java-guruja, mikä on ilo huomata :-). Ehkä joskus voin itsekin auttaa jotakuta tänne kirjoittavista. Kiitos siis vielä kerran!
Sain koodisi avulla ratkaistua jo pitkään minua hiertäneen ongelmani. Tuon parempaa esimerkkiä et olisi voinut antaa.
Sovelluksessani haetaan tietoa tietokannasta, joka sijaitsee eri koneella kuin webbiserveri. Nyt homma toimii kuin buickki ja n. 4 kertaa nopeammin kuin aiemmin. En voi kyllin kiittää avustasi!