QA@IT

ログインしてwebアプリケーションを動作させるとHTTP STATUS404エラー発生

4544 PV

お世話になります。

Java1.7.0
tomcat7
Eclipse4.2
servlet3.0

(tsukaeru.net)
http://www.tsukaeru.net/jelastic/
Java専用サーバー「Jelastic」(2週間無料お試し機能使用中)
アップロード画面
http://shop.java-eclipse.biz/book/

下記コードでJSPの詳細ボタンをおすと
URLに http://hoge.com/project名/baseLayout/catalogdetailと表示され、
正常に詳細画面 (http://hoge.com/project名/baseLayout/productLayout.jsp)の内容が表示されます。
しかし、ログインしてクライアントの名前が表示された画面で詳細ボタンを押すと
URLに http://hoge.com/project名/baseLayout/baseLayout/catalogdetailと表示され、
HTTP STATUS 404エラーになってしまいます。
このようなケースはどこかがどう違うのでしょうか?
ご教授願います。

ちなみに詳細ボタンを押して、詳細画面を表示させてから、
nextボタンを押しても、URLに http://hoge.com/project名/baseLayout/baseLayout/nextと表示され、
HTTP STATUS 404エラーになってしまいます。

hoge.jsp

<c:forEach var="var2" items="${object}" >
<table border="1">
 <tr bgColor="#ff5500">
  <th></th>
  <th>本名</th>
  <th>価格</th>
  <th></th>
 </tr>
 <c:forEach var="var" items="${products}" begin="${var2.offset}" end="${var2.offset + 2}">
 <tr bgColor="#ff5500">
  <td align="center" width="40">${var.id}</td>
  <td width="120">${var.name}</td>
  <td align="right" width="70">${var.price}円</td>      
  <td>
  <form action="baseLayout/catalogdetail" method="post">
   <input type="hidden" name="id" value="${var.id}"/><br>
   <input type="submit" name="submit" value="詳細"/>
  </form>
  </td>  
 </tr>
 </c:forEach>
</table>
<table>
 <tr>
  <td>
   <c:if test="${var2.offset >= 0}">
    <c:if test="${var2.offset < products.size()-3 }">
     <form method="post" action="baseLayout/next">
      <input type="hidden" name="offset" value="${var2.offset}"/>   
      <input type="submit" name="submit" value="次の3件"/>
     </form>
    </c:if>
   </c:if>
  </td>
  <td>
   <c:if test="${2 < var2.offset + 1}">
    <c:if test="${var2.offset < products.size()}">
     <form method="post" action="baseLayout/back">
      <input type="hidden" name="offset" value="${var2.offset}"/>   
      <input type="submit" name="submit" value="前の3件"/>
     </form>
    </c:if>
   </c:if>
  </td>
 </tr>
</table>
</c:forEach>

hoge.java

@WebServlet(urlPatterns = {"/baseLayout/catalogdetail"})
public class CatalogDetailShowServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    (途中略)

    getServletContext().getRequestDispatcher("/baseLayout/productLayout.jsp").forward(request,response);

    }
}

web.xml

<servlet>
  <servlet-name>CatalogShowServlet</servlet-name>
  <servlet-class>controller.catalog.CatalogShowServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>CatalogShowServlet</servlet-name>
  <url-pattern>/controller/catalog/CatalogShowServlet</url-pattern>
 </servlet-mapping>
<welcome-file-list>
  <welcome-file>baseLayout/catalog</welcome-file>
</welcome-file-list>

[追記]
_______________________________________

JSPのFORMタグの中のactionを"baseLayout/catalogdetail"や"baseLayout/next"や"baseLayout/back"と
せず、ただ"catalogdetail"や"next"や"back"すると、
URLに http://hoge.com/project名/catalogdetailと表示され、
HTTP STATUS 404エラーになってしまいます。
しかし、ログインボタン(コードは遷移先をaタグでとばしている)をおしてログインしてから、
詳細ボタンを押すと、
URLに http://hoge.com/project名/baseLayout/catalogdetailと表示され、
正常に詳細画面 (http://hoge.com/project名/baseLayout/productLayout.jsp)の内容が表示されます。
ですが、その後さらにnextボタンを押すと、
URLに http://hoge.com/project名/baseLayout/baseLayout/nextと表示され、
HTTP STATUS 404エラーになってしまいます。
HTMLコードも、「ソースの表示」をみながら確認していますが、特にエラーが出るまえのコード(action属性)に変化がないのです。
つまり、ここではまってます。flied_onion様がご指摘のactionにはjspが格納されているbaseLayoutフォルダ名をつけないと、
URLに http://hoge.com/project名/catalogdetailと表示され、
正常に詳細画面 (http://hoge.com/project名/baseLayout/productLayout.jsp)の内容が表示されないのです。

強制的にこの問題を解決しようというのなら、
baseLayoutフォルダに親jspをおき、includeされるjspをpartフォルダにいれるという配置をやめて、
すべてのjspをproject配下に配置すればよいのですが、
それでは芸がないような気がしてます。
なんとかこのフォルダ構成でやっていきたいのです。

  • そういうトライアンドエラーな対処ではなく、その状況でそのactionなら当然そうなると、思えるようになって下さい。
    対策が思いつかないときは回答するつもりですが、ここで答えだけ書いてもまた同じ壁にぶつかると思います。
    -
  • actionしか見てないみたいですが、各局面でのurlもセットで考えましょう -

回答

結論から言えば、action属性をそのように指定しているからだと思いますが、
HTMLのFormタグの属性(特にaction属性)を調べてみるといいと思います。

そしてそれぞれの場面で自分のサーブレット/jspプログラムが生成しているHTMLがどのようになっているのか(Formタグの部分)を見てみてください。

その後対策が思いつかないようであればコメントをつけてください。

編集 履歴 (0)
  • 早速試してみます。有り難うございます。 -
  • 追記しましたが、頑張ってみます。 -
  • flied_onion様、回答をおこしました。ご高覧下さい。 -

いつもお世話になっています、flied_onion様。

長くなりますので、回答おこします。
結果からいうとコードを修正して正常動作するようになりました。
flied_onion様から戴いたヒントを元にです。
つまり、action属性はフォルダ名をつけないということを前提にして、
コードの変更を考えました。

catalog.jsp

<c:forEach var="var2" items="${object}" >
<table border="1">
 <tr bgColor="#ff5500">
  <th></th>
  <th>本名</th>
  <th>価格</th>
  <th></th>
 </tr>
 <c:forEach var="var" items="${products}" begin="${var2.offset}" end="${var2.offset + 2}">
 <tr bgColor="#ff5500">
  <td align="center" width="40">${var.id}</td>
  <td width="120">${var.name}</td>
  <td align="right" width="70">${var.price}円</td>      
  <td>
  <form action="catalogdetail" method="post">
   <input type="hidden" name="id" value="${var.id}"/><br>
   <input type="submit" name="submit" value="詳細"/>
  </form>
  </td>  
 </tr>
 </c:forEach>
</table>
<table>
 <tr>
  <td>
   <c:if test="${var2.offset >= 0}">
    <c:if test="${var2.offset < products.size()-3 }">
     <form method="post" action="next">
      <input type="hidden" name="offset" value="${var2.offset}"/>   
      <input type="submit" name="submit" value="次の3件"/>
     </form>
    </c:if>
   </c:if>
  </td>
  <td>
   <c:if test="${2 < var2.offset + 1}">
    <c:if test="${var2.offset < products.size()}">
     <form method="post" action="back">
      <input type="hidden" name="offset" value="${var2.offset}"/>   
      <input type="submit" name="submit" value="前の3件"/>
     </form>
    </c:if>
   </c:if>
  </td>
 </tr>
</table>
</c:forEach>

CatalogDetailShowServlet.java

@WebServlet(urlPatterns = {"/catalogdetail"})
public class CatalogDetailShowServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    (途中略)

    getServletContext().getRequestDispatcher("/baseLayout/productLayout.jsp").forward(request,response);

    }
}

web.xml

<servlet>
  <servlet-name>CatalogDetailShowServlet</servlet-name>
  <servlet-class>controller.catalog.CatalogDetailShowServlet</servlet-class>
 </servlet>
<servlet>
  <servlet-name>CatalogShowServlet</servlet-name>
  <servlet-class>controller.catalog.CatalogShowServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>CatalogDetailShowServlet</servlet-name>
  <url-pattern>/baseLayout/catalogdetail</url-pattern>
 </servlet-mapping>
<servlet-mapping>
  <servlet-name>CatalogShowServlet</servlet-name>
  <url-pattern>/controller/catalog/CatalogShowServlet</url-pattern>
 </servlet-mapping>
<welcome-file-list>
  <welcome-file>/baseLayout/catalog</welcome-file>
</welcome-file-list>

ただし、welcome-fileのCatalogShowServlet.javaのアノテーションは以下で変更しませんでした。
つまりフォルダ名はここでは必要だったのです。

CatalogShowServlet.java

@WebServlet(urlPatterns = { "/baseLayout/catalog" })
public class CatalogShowServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet (HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException{
        this.doPost(request, response);
    }

        (途中略)

    getServletContext().getRequestDispatcher("/baseLayout/productLayout.jsp").forward(request,response);

    }
}

この度もヒントを下さって有り難うございます。
今回というか現在は「使える.net」さんのサーバーで、
どんな感じでインターネットにアップロードされるか試してみました。
インターネットで調べても、javaの使えそうなサーバーはここにしかなかったからです。
flied_onion様が以前ご推薦して下さった「1strentalserver」はresponseが遅いので、
僕としてはあまり上手くいかないなと思ってやめました。
僕としてはあくまでCentOSでアップロードするのを目標にしております。
また、質問も出てくると思いますが、その際はまた宜しくお願い致します。
この度もありがとうございました。

編集 履歴 (2)
ウォッチ

この質問への回答やコメントをメールでお知らせします。