1

2 つの機能を統合したかったのです。

実行可能な解決策を得た後、私はコードをもう少しいじることに決め、これを思いつきました:

package hu.flux.helper;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import javax.servlet.jsp.JspWriter;
import com.objectmentor.library.web.framework.mocks.*;


// A holder for formatting data 
public class NameAndAddress 
{
    public String firstName;
    public String middleName;
    public String lastName;
    public String address1;
    public String address2;
    public String city;
    public String state;
    public String zip;

    public String FormattedString()
    {
        String formattedString = "<PRE>\n" + firstName;

        // Add the middle name only if it contains data.
        if ((middleName != null) && (middleName.length() > 0)) 
            {formattedString += " " + middleName;}

        formattedString += " " + lastName + "\n";

        formattedString += address1  + "\n";

        if ((address2 != null) && (address2.length() > 0))
            formattedString += address2 + "\n";

        formattedString += city + ", " + state + " " + zip + "\n</PRE>";
        return formattedString;
    }

    // Print out the name and address.
    public void print(Writer writer) {
    long now = System.currentTimeMillis();
    System.out.println("--Entering-- " + now);
    PrintWriter p = new PrintWriter (writer);
        p.write(this.FormattedString());
            now = System.currentTimeMillis();
        System.out.println("--Exiting-- "  + now);
    }

    /*
    public void print(JspWriter out) throws java.io.IOException 
    { print (new PrintWriter(out)); }
    */

    @SuppressWarnings("deprecation")
    public static void main (String args[])
    {
        NameAndAddress naa = new NameAndAddress();
        naa.firstName = "Brian";
        naa.middleName = "Matthew";
        naa.lastName = "Kessler";
        naa.address1 = "Tatra u. 15/b V/3";
        naa.city = "Budapest";
        naa.state = "Hungary";
        naa.zip = "HU-1136";

        System.out.println("\nTesting PrintWriter...");
        PrintWriter p = null;
        try { p = new PrintWriter("d:/temp/pwriter_text.txt"); } 
        catch (FileNotFoundException e) 
        { 
            System.err.print ("Can not create new PrintWriter: " + e);
            e.printStackTrace();
        }
        naa.print(p);
        p.flush();

        FileInputStream fis;
        DataInputStream dis;
        try 
        { 
            fis = new FileInputStream("d:/temp/pwriter_text.txt");
            dis = new DataInputStream (fis);
            while (dis.available() != 0)
                { System.out.println(dis.readLine()); }
            dis.close();
        }
        catch (Exception e)
        {
            System.err.println("File input error");
        }


        System.out.println("\nTested PrintWriter...");
        System.out.println("---------------------");

        System.out.println("\nTesting JSPWriter...");
        JspWriter j = null;
        naa.print(j);
        System.out.print("\nTested JSPWriter...");
        System.out.println("---------------------");

        System.out.println("\nTesting MockJspWriter");
        MockJspWriter m = null;
        m = new MockJspWriter(255, true);
        naa.print(m);
        System.out.print(m.getContent());
        System.out.println("\nTested MockJSPWriter...");
        System.out.println("---------------------");
    }
}

print() メソッドが JspWriter と PrintWriter の両方をキャッチすることを期待していました。

このソリューションは PrintWriter では問題なく機能しましたが、これをコンソール アプリケーションとして実行しようとすると、次の出力が得られます。

Testing PrintWriter...
--Entering-- 
--Exiting-- 
<PRE>
Brian Matthew Kessler
Tatra u. 15/b V/3
Budapest, Hungary HU-1136
</PRE>

Tested PrintWriter...
---------------------

Testing JSPWriter...
--Entering-- 
Exception in thread "main" java.lang.NullPointerException
    at hu.flux.helper.NameAndAddress.print(NameAndAddress.java:46)
    at hu.flux.helper.NameAndAddress.main(NameAndAddress.java:101)

ただし、JSP から print(Writer writer) にアクセスしようとすると、別のエラーが発生します。

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: javax.servlet.ServletException: java.lang.NoSuchMethodError: hu.flux.helper.NameAndAddress.print(Ljavax/servlet/jsp/JspWriter;)V
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:492)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:407)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
root cause

javax.servlet.ServletException: java.lang.NoSuchMethodError: hu.flux.helper.NameAndAddress.print(Ljavax/servlet/jsp/JspWriter;)V
    org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:898)
    org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:827)
    org.apache.jsp.Address_jsp._jspService(Address_jsp.java:92)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:68)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:376)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
root cause

java.lang.NoSuchMethodError: hu.flux.helper.NameAndAddress.print(Ljavax/servlet/jsp/JspWriter;)V
    org.apache.jsp.Address_jsp._jspService(Address_jsp.java:81)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:68)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:376)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.2 logs.

Apache Tomcat/7.0.2

JSP から呼び出す場合、次のコードを追加することで、JspWriter が機能するクラスを呼び出すことができます。

public void print(JspWriter out) throws java.io.IOException 
    { print (new PrintWriter(out)); }

ただし、コンソール アプリケーションから JspWriter を使用しようとすると (テストのため -- コンソールで JspWriter を使用する必要はないと思います!)、上記のコンソール エラーはこの関数に移されます。

print(JspWriter out) で JSP の問題を解決できるのであれば、コンソール アプリの問題も解決できるのではないでしょうか。

また、JspWriter が Writer オブジェクトである場合、コンソールから呼び出されるか、JSP から呼び出されるかに関係なく、常に Writer オブジェクトであるべきではないでしょうか。

4

6 に答える 6

3

この例外は、 に変更print(JspWriter)した後に JSP コードが再コンパイルされていないprint(Object)ため、呼び出しを試みてprint(JspWriter)も見つからないことを示しています。

再コンパイルを強制するために、JSP ページを変更できます。

于 2010-10-03T14:23:23.763 に答える
1

と の両方が のサブクラスであるため、投稿したものは機能するはずです(もちろん、両方とも のサブクラスですPrintWriter) 。テスト コードまたは環境に何か問題があるようです。JspWriterWriterObject

たぶん、単純化された例を試して、それが機能するかどうかを確認してから、そこから構築することができます. ここから始めることをお勧めします:

public class Test
{
    public void print(Writer writer) throws IOException
    {
        if (writer == null)
            System.out.println("Null writer");
        else
        {
            writer.write("hello");
            writer.flush();
        }
    }

    public static void main(String args[]) throws IOException
    { 
        Test test = new Test();

        System.out.print("Testing PrintWriter...");
        PrintWriter p = new PrintWriter("d:/temp/pwriter_text.txt");
        test.print(p);
        System.out.print("Tested PrintWriter...");

        System.out.print("Testing JspWriter...");
        JspWriter j = null;
        test.print(j);
        System.out.print("Tested JspWriter...");
    }
}

これはコンパイルして実行する必要があります。2 回目test.print()に呼び出されると、JspWriter渡されるものは になりますがnull、取得するべきではありませんNoSuchMethodError。これが機能する場合は、コードを取得して、サーブレット/JSP ページからテストします。うまくいけば、これは問題を見つけるのに役立ちます。

于 2010-10-03T16:30:04.007 に答える
1

これは、Java コンパイラが JspWriter オブジェクトで PrintWriter.print メソッドを見つけようとするためです。print メソッドがありますが、このメソッドは別のクラスのものなので一致しません。Java はダックタイピングをサポートしておらず、それを防ぐために多大な努力を払っています。

また、プログラミング ロジックで例外を使用することも悪い習慣と見なされます。

あなたはsthgのようにする必要があります

    try
    { 
       if (out instanceof PrintWriter) {
          ((PrintWriter) out).print(this.formattedString()); 
       } else if (out instanceof JspWriter) {
          ((JspWriter) out).print(this.formattedString()); 
       } else {
          throw new IllegalArgumentException("NameAndAddress.print expected ether a PrintWriter or a JspWriter but received a " + out.getClass().getName());
       }
    catch (Exception ex)
    { System.err.println("\"out\" is not a printable type: " + ex); }

ところで: Java のメソッドは、慣例により小文字で始める必要があります。

于 2010-10-03T14:22:18.300 に答える
0

a にキャストしてメソッドを開始するPrintWriterので、jvm がメソッドを最適化した可能性があります。JspWriterは からサブクラス化されていないためPrintWriter、最善の策は次の 2 つのメソッドを記述することです。

public void print(JspWriter out) 
{ 
    if (out == null) return;
    try {
        out.print(this.FormattedString());
    } Except (IOException e) {
        // handle error 
    }
}

public void print(PrintWriter out) 
{ 
    if (out == null) return;
    try {
        out.print(this.FormattedString());
    } Except (IOException e) {
        // handle error 
    }
}

JspWriter と PrintWriter だけが共通のインターフェースを持っていれば... はぁ。

于 2010-10-03T14:24:09.883 に答える
0

Your print() casts Object to a PrintWriter. But when you pass in a JspWriter which isn't PrintWriter, the cast fails.

However, PrintWriter and JspWriter are both descended from Writer. Can you change your print() method to accept a Writer instead of an Object, and then use the Writer.write() method within print()? This is common to both classes.

This:

public void print(Writer writer) {
    try {
        writer.write(this.FormattedString());
    } catch (IOException e) {
        // log something...
    }
}
于 2010-10-03T14:26:00.663 に答える
0

JspWriter は PrintWriter ではありません

次のように、元のライターを印刷ライター内にラップできます。

if (out instance of Writer) {
 PrintWriter p = new PrintWriter((Writer) out));
 p.print...
}
于 2010-10-03T14:21:59.517 に答える