0

行 clanovi = ((HashMap) in.readObject()); のときに EOF 例外が発生します。from メソッド load() が実行されますが、常にではありません。これは、サーブレットから load メソッドを 5 ~ 6 回、場合によっては 10 回呼び出した後に発生し、完全にランダムです。私を助けてください、明日の朝のプロジェクト防御のためにこれを解決する必要があります:(

ClanPostave はシリアライズ可能です。load メソッドに flush() を追加しようとしましたが、何も役に立ちませんでした。

public class Clanovi implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;


HashMap<String, ClanPostave> clanovi = new HashMap<String, ClanPostave>();

public HashMap<String, ClanPostave> getClanovi() {
    return clanovi;
}

public void setClanovi(HashMap<String, ClanPostave> clanovi) {
    this.clanovi = clanovi;
}


public synchronized void save(String path){

    try {

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path + "/clanovi.dat"));
        out.writeObject(clanovi);
        out.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@SuppressWarnings("unchecked")
public synchronized void load(String path){

    try {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(path + "/clanovi.dat"));
        clanovi = ((HashMap<String,ClanPostave>) in.readObject());
        in.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

スタックトレース:

java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.defaultReadObject(Unknown Source)
    at java.util.Calendar.readObject(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor25.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at java.util.HashMap.readObject(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at beans.Clanovi.load(Clanovi.java:52)
    at servlets.DodajClana.doPost(DodajClana.java:51)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)

Joni のおかげで EOFException はなくなりましたが、今はこれに問題があります:

try {
            clanovi1.dodajClana(new ClanPostave(idclana,ime,prezime,mesto,new GregorianCalendar(datumGodina, datumMesec, datumDan),biografija,uloga));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        clanovi1.save(path);
        clanovi1.load(path);
        HashMap<String, ClanPostave> clanovi = clanovi1.getClanovi();

このコードの後、HashMap は空です。そして、ジョニによって提案されたこの変更の前は、その try ブロックに追加された値で満たされていました。何が間違っている可能性がありますか?

サーブレット全体は次のとおりです。

 package servlets;

    import java.io.IOException;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.HashMap;

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

    import beans.ClanPostave;
    import beans.Clanovi;
    import beans.Korisnik;

    /**
     * Servlet implementation class DodajClana
     */
    public class DodajClana extends HttpServlet {
        private static final long serialVersionUID = 1L;



        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.getRequestDispatcher("index.jsp").forward(request, response);
        }
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext ctx = getServletContext();   
            Korisnik korisnik = (Korisnik) request.getSession().getAttribute("korisnik");

            if(korisnik != null && korisnik.getAdmin()){
            String path = ctx.getRealPath("");
            String idclana = request.getParameter("idclana");
            String ime = request.getParameter("ime");
            String prezime = request.getParameter("prezime");
            String mesto = request.getParameter("mesto");
            int datumGodina = Integer.parseInt(request.getParameter("datumGodina"));
            int datumMesec = Integer.parseInt(request.getParameter("datumMesec"))-1;
            int datumDan = Integer.parseInt(request.getParameter("datumDan"));
            String biografija = request.getParameter("biografija");
            String uloga = request.getParameter("uloga");

            System.out.println(idclana);

            Clanovi clanovi1 = new Clanovi();
            clanovi1.load(path);

            if(!isDateValid(datumGodina, datumMesec, datumDan)){
                System.out.println("ne valja datum");
                request.setAttribute("greska1", "Nevalidan datum!");
            }

            if(clanovi1.getClanovi().containsKey(idclana)){
                System.out.println("ne valja id");
                request.setAttribute("greska2", "Clan sa tim ID-jem vec postoji u bazi!");
            }

            if((!isDateValid(datumGodina, datumMesec, datumDan))||clanovi1.getClanovi().containsKey(idclana)){

                request.getRequestDispatcher("/WEB-INF/clanGreska.jsp").forward(request, response);
            }

            boolean test = !((!isDateValid(datumGodina, datumMesec, datumDan))||(clanovi1.getClanovi().containsKey(idclana)) || ((!isDateValid(datumGodina, datumMesec, datumDan))||clanovi1.getClanovi().containsKey(idclana)));
            System.out.println(test);
            if(test){

                try {
                    clanovi1.dodajClana(new ClanPostave(idclana,ime,prezime,mesto,new GregorianCalendar(datumGodina, datumMesec, datumDan),biografija,uloga));
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                clanovi1.save(path);
                try {
                    System.out.println(clanovi1.getClan(idclana));
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                try {
                    System.out.println(clanovi1.getClan(idclana));
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                HashMap<String, ClanPostave> clanovi = clanovi1.getClanovi();
                ctx.setAttribute("clanovi", clanovi);       
                request.getRequestDispatcher("index.jsp");
            }

            }                   

            else request.getRequestDispatcher("index.jsp").forward(request, response);
        }


        public synchronized boolean isDateValid(int year, int month, int day) {  
            boolean valid = true;  
            Calendar calendar = new GregorianCalendar(year, month, day);  
            if (year != calendar.get(Calendar.YEAR)) {  
                valid = false;  
            }  
            else if (month != calendar.get(Calendar.MONTH)) {  
                valid = false;  
            }  
            else if (day != calendar.get(Calendar.DAY_OF_MONTH)) {  
                valid = false;  
            }  
            return valid;  
        }  



    }
4

2 に答える 2

1

不完全なファイルの読み取りを防ぐ 1 つの方法は、一時ファイルに書き込み、名前を変更することです。

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path + "/clanovi.tmp"));
    out.writeObject(clanovi);
    out.close();
    new File(path + "/clanovi.tmp").renameTo(new File(path + "/clanovi.ovi"));

これは、loadプロセスが最初の実行でファイルを見つけられないか、古いデータを読み取る可能性があることを意味します。

于 2013-07-07T20:32:03.413 に答える
-1

同期されたブロック/関数を使用して、シリアル化されたファイルをロードおよび保存できる場合があります。

何かのようなもの -

 public enum Operation {
           LOAD,
           SAVE;      
 }

 synchronized void loadOrSave(String path, Operation operation) {
     if (operation == Operation.LOAD) {
         //do load here
     } else {
         //do save here
     }

 }
于 2013-07-07T21:05:48.527 に答える