带存储过程的空白Servlet

时间:2017-11-05 19:00:34

标签: java jsp servlets stored-procedures oracle11g

我在编程时很新,所以对我来说有点难啊xx,但是我正在尝试用java(servlet)上的存储过程执行登录(JSP),遗憾的是servlet页面只给了我一个空白页面,并没有将我重定向到主页homeAlumno.jsp(目前只有一个Hello World的JSP),我正在使用netbeans IDE 8.2(带有Tomcat服务器),而数据库是带有几个的Oracle 11g Express Edition表格,任何帮助或建议将不胜感激。

pd:第一篇文章,对不起,如果我发错了:'D

而heere是代码

的login.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Login CEM</title>
    </head>
    <body style="text-align: center">
        <h1>Menú CEM</h1>
        <form method="POST" action="serv_login">
            <input type="text" name="usuario"  placeholder="Nombre"/>
            <input type="password" name="pass"  placeholder="Password" />
            <input type="submit" value="Login"/>
        </form>
    </body>
</html>

Conexion类(连接)

package modelo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

    public class Conexion {
        private static Connection cnx = null;
       public static Connection obtener() throws SQLException,    ClassNotFoundException {
      if (cnx == null) {
         try {
         Class.forName("oracle.jdbc.OracleDriver");
         cnx =  DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "system", "123");
     } catch (SQLException ex) {
        throw new SQLException(ex);
     } catch (ClassNotFoundException ex) {
        throw new ClassCastException(ex.getMessage());
     }
  }
  return cnx;
 }
    public static void cerrar() throws SQLException {
          if (cnx != null) {
             cnx.close();
     }
   }
}

serv_login.java(servlet)

package controlador;

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import modelo.Conexion;

/**
*
* @author asd
 */
@WebServlet(name = "serv_login", urlPatterns = {"/serv_login"})
public class serv_login extends HttpServlet {

/**
 * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
 * methods.
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
    protected void processRequest(HttpServletRequest request,    HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");

    try {

        String usuario = request.getParameter("usuario");
        String pass = request.getParameter("pass");



        CallableStatement stmt = Conexion.obtener().prepareCall("{call LoginJava(?,?)}");

        stmt.setString(1, usuario);
        stmt.setString(2, pass);


        ResultSet rs = stmt.executeQuery();
        RequestDispatcher rd;

        rd = request.getRequestDispatcher("login.jsp");

        while(rs.next()) {

            if(rs.getString("NOMBRE_ALUMN").equals(request.getParameter("usuario")) && rs.getString("PASS_ALUMN").equals(request.getParameter("pass"))){                                            
                    request.getRequestDispatcher("homeAlumno.jsp"); 
                    rd.forward(request, response);  
                }else{
                    request.getRequestDispatcher("login.jsp");  
                    rd.forward(request, response);
                } 

            }

    } catch (SQLException ex) {
            ex.getMessage();

    } catch (ClassNotFoundException ex) {
        Logger.getLogger(serv_login.class.getName()).log(Level.SEVERE, null, ex);
        ex.getMessage();
    }

}

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
 * Handles the HTTP <code>GET</code> method.
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    processRequest(request, response);
}

/**
 * Handles the HTTP <code>POST</code> method.
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    processRequest(request, response);
}

/**
 * Returns a short description of the servlet.
 *
 * @return a String containing servlet description
 */
@Override
public String getServletInfo() {
    return "Short description";
}// </editor-fold>

}

存储过程(Oracle DB)

create or replace procedure LoginJava(usuario ALUMNO.USU_ALUMN%type,
contraseña ALUMNO.PASS_ALUMN%type)                              
as 
    v_usuario ALUMNO.USU_ALUMN%type;
    v_contraseña ALUMNO.PASS_ALUMN%type;
begin
    select USU_ALUMN, PASS_ALUMN into v_usuario, v_contraseña from ALUMNO
    where USU_ALUMN = usuario and PASS_ALUMN = contraseña;           
    return;
end;

谢谢!

1 个答案:

答案 0 :(得分:0)

以下是您的工作:

rd = request.getRequestDispatcher("login.jsp");

... some code ...

request.getRequestDispatcher("homeAlumno.jsp"); 
rd.forward(request, response);

request.getRequestDispatcher("homeAlumno.jsp")行只会创建一个全新的RequestDispatcher,然后将其丢弃(因为它不会保存到任何变量中)。在下一行中,您只需前往login.jsp

尝试执行以下操作:

request.getRequestDispatcher("homeAlumno.jsp").forward(request, response);

另一件事:在你的循环中你理论上可以制作几个前锋(如果你的程序返回多个记录)。为了以防万一,我会添加一个中断(或将while替换为if)。

还有一件事:我不是Oracle存储过程语法的优秀专家,但似乎你没有从你的程序中返回任何结果集,所以你的循环体根本不会被执行(甚至一次)。

尝试做这样的事情:

select count(*) CNT from ALUMNO
where USU_ALUMN = usuario and PASS_ALUMN = contraseña; 

然后(而不是你的while循环):

rs.next();
if (rs.getInt("CNT") > 0) {
    // .. there is such a user, do the forward
} else {
    // no such user, or password mismatch
}

如果你不介意,可以提出几点建议。

首先,您似乎计划在数据库中以纯文本格式存储密码。这是一个坏主意:使用带有盐的哈希,例如像BCrypt这样的东西。以下是更多信息:https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/

此外,您正在使用密码身份验证重新发明轮子。如果这不仅仅是一个将在几天内被丢弃的学生项目,我建议您查看Spring Security(独立或Spring Boot)或类似的安全框架。这使得身份验证变得更加容易。