ayuda con los request de un servlet.

q tal amigos, es mi primer post en el foro y ya estoy dando problemas.

estoy trabajando en una aplicacion web que obtiene parametros de un html por el metodo post.

la aplicacion funciona muy bien con solo una ejecucion, es decir pongo mi aplicacion en el servidor tomcat, y sucede algo raro el cliente1 accesa a la aplicacion y la ejecuta, ,el proceso comienza normalmente pero llega el cliente2 y ejecuta la aplicacion, entonces el servidor deja de realizar la peticion del cliente1 y comienza a realizar la peticion del cliente2, ya puse manejo de sesiones, el problema es que creo algunas tablas temporales en la aplicacion, les adjunto codigo y espero alguien m pueda ayudar.

<pre>
public class graphic extends HttpServlet {
      int vintop=0,vinbot=0;
public int usuario=0;
public static int user;
HttpSession todo_session;

    /**
     * Processes requests for both HTTP <code>GET

and POST 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, SQLException {
/////variables en donde se guardan los resultados de la seleccion en la primera pagina
String Todo="";
String vin,vintext1,vintext2,model,market;
String eng1,eng2,eng3,eng4,eng5,eng6;///variables engine number
String pid1,pid2,pid3,pid4,pid5,pid6;///variables de partid
String group;//variable grupos
String dc1,dc2,dc3,dc4,dc5,dc6;//variables damage code
String repairr;//variable repair replace
String sdc1,sdc2,sdc3,sdc4,sdc5,sdc6;///Variables service dealer code
String cspn1,cspn2,cspn3,cspn4,cspn5,cspn6;
String tipografica;
String vinop;
int opvin=0,opcmodel=0;
String operador="";
int armacadena=0;
String cadena="",cadenaventas="",subc1="",subc2="",subc3="";
String cadfinalgarantias="",cadfinalventas="";
String subc7="";
String consultaor1="",consultaor2="",consultaor3="",consultaor4="",consultaor5="";
String subc3sales;
String consultaorv4="";
calcpoints garant;
calcpoints vtas;
calcpoints usuarios;
boolean paso1;
int numerousuario;
boolean paso2;
response.setContentType("text/html;charset=UTF-8");

vin=request.getParameter("opcionvin").trim();
vintext1=request.getParameter("vin1").trim();
vintext2=request.getParameter("vin2").trim();
model=request.getParameter("opcionmodel").trim();
market=request.getParameter("opcionmarket").trim();
eng1=request.getParameter("E1").trim();
eng2=request.getParameter("E2").trim();
eng3=request.getParameter("E3").trim();
eng4=request.getParameter("E4").trim();
eng5=request.getParameter("E5").trim();
eng6=request.getParameter("E6").trim();
pid1=request.getParameter("PID1").trim();
pid2=request.getParameter("PID2").trim();
pid3=request.getParameter("PID3").trim();
pid4=request.getParameter("PID4").trim();
pid5=request.getParameter("PID5").trim();
pid6=request.getParameter("PID6").trim();
group=request.getParameter("opciongroup").trim();
dc1=request.getParameter("DC1").trim();
dc2=request.getParameter("DC2").trim();
dc3=request.getParameter("DC3").trim();
dc4=request.getParameter("DC4").trim();
dc5=request.getParameter("DC5").trim();
dc6=request.getParameter("DC6").trim();
repairr=request.getParameter("RR").trim();
sdc1=request.getParameter("SDC1").trim();
sdc2=request.getParameter("SDC2").trim();
sdc3=request.getParameter("SDC3").trim();
sdc4=request.getParameter("SDC4").trim();
sdc5=request.getParameter("SDC5").trim();
sdc6=request.getParameter("SDC6").trim();
cspn1=request.getParameter("CSPN1").trim();
cspn2=request.getParameter("CSPN2").trim();
cspn3=request.getParameter("CSPN3").trim();
cspn4=request.getParameter("SCPN4").trim();
cspn5=request.getParameter("SCPN5").trim();
cspn6=request.getParameter("SCPN6").trim();

///recolecto todos los parametros del html

///////aqui tengo algunas operaciones para formar una cadena sql
///////.............
//////.........

//////////paso las cadenas a la clase calpoints
garant=new calcpoints(cadfinalgarantias,cadfinalventas);
paso1= garant.opgarantias();
paso2=garant.opventas();

/////////desactivo la sesion despues de hacer todas las operaciones.
todo_session.invalidate();

/////fin desactivo la sesion

JOptionPane.showMessageDialog(null,"valor sesion"+todo_session.getAttribute("id").toString());

///////////aqui genero una grafica con jfreechart

final LineChartDemo1 demo = new LineChartDemo1("Line Chart Demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);

response.setContentType("image/jpeg");

OutputStream salida = response.getOutputStream();
JFreeChart grafica = crearChart();

int ancho = 1000;
int alto =900;

ChartUtilities.writeChartAsJPEG(salida,grafica,ancho,alto);
user= calcpoints.user();

salida.close();
//// fin creando grafica.

public JFreeChart crearChart() throws SQLException ////este metodo obtiene el dataset a graficar.
{
JFreeChart chart;
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// este código no es optimo ..... hay que usar pools
try
{
Driver d = (Driver)Class.forName("com.mysql.jdbc.Driver").newInstance();
}
catch (Exception e)
{
System.out.println(e);
}

// GET CONNECTION
Connection con = null;

try
{
con = DriverManager.getConnection("jdbc:mysql://localhost/calidad3","root","sibok");
}
catch(Exception e)
{
System.out.println(e);
}

dataset = (DefaultCategoryDataset) LineChartDemo1.createDataset();
chart = ChartFactory.createLineChart("",
"MIS",
"Fallas x 1000 vehiculos",
dataset,
PlotOrientation.VERTICAL,
true,
true,
true);

chart.setBackgroundPaint(Color.white);

final CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setRangeGridlinePaint(Color.lightGray);

// customise the range axis...
final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
rangeAxis.setAutoRangeIncludesZero(true);
// customise the renderer...
final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
///con esto generaremos las etiquetas de los valores
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setItemLabelsVisible(true);

renderer.setSeriesStroke(
0, new BasicStroke(
2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
1.0f, new float[] {10.0f, 6.0f}, 0.0f
)
);
renderer.setSeriesStroke(
1, new BasicStroke(
2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
1.0f, new float[] {6.0f, 6.0f}, 0.0f
)
);
renderer.setSeriesStroke(
2, new BasicStroke(
2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
1.0f, new float[] {2.0f, 6.0f}, 0.0f
)
);
// OPTIONAL CUSTOMISATION COMPLETED.

try
{
con.close();
}
catch(Exception e)
{
System.out.println("Error al desconectar " + e);
}

int user= calcpoints.user();

String eliminafinal="drop table final"+user+";";
//
conect cnn=new Conexion.conect();
try{
Statement st11 = cnn.getConnection().createStatement();

st11.executeUpdate(eliminafinal);

}catch(SQLException e)
{
System.out.println("Error: " + e.getMessage());
System.out.println("eliminando tabla final" );
cnn.desconectar();
}
//////////////////////////////////////////
/*
conect cnni=new Conexion.conect();
String complj="delete from calidad3.usrno where No="+user+";";

try{
Statement stj = cnni.getConnection().createStatement();

stj.executeUpdate(complj);

}catch(SQLException e)
{
System.out.println("Error: " + e.getMessage());
JOptionPane.showMessageDialog(null,"Error eliminando user ");
cnni.desconectar();
}
//////////////////////////////////////

*
*/
return chart;
}

//
/**
* Handles the HTTP GET 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 {
// try {
// processRequest(request, response);
//} catch (SQLException ex) {
// Logger.getLogger(graphic.class.getName()).log(Level.SEVERE, null, ex);
//}

}

/**
* Handles the HTTP POST 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 {

try {
////////////////////////aqui activo la sesion antes de dar respuesta al usuario.
todo_session =request.getSession();

String x=todo_session.getId().toString();

todo_session.setAttribute("id",x);

JOptionPane.showMessageDialog(null,"usuario..."+todo_session.getAttribute("id").toString());

//////////aqui hago la llamada a la respuesta generada que genera la grafica.
processRequest(request, response);
//////antes aqui habia puesto el invalidate de la sesion.

} catch (SQLException ex) {

JOptionPane.showMessageDialog(null,"error en la respuesta");

}

}

}// fin clase

como pueden ver en el servlet solo recolecto parametros de graficacion generados por una clase, las operaciones que realizo para obtener las coordenadas a graficar son muy conplejas por eso lo hago de esa manera.

la clase calc points q m genera las coordenas luce asi.

<pre>
////aqui los metodos getters y setters
////
package Clases;
import Conexion.conect;
import javax.swing.JOptionPane;
import java.sql.*;

public class calcpoints {

   
    public boolean opgarantias(){
       
      String compli;

      conect cnni = new conect();
 
    compli="select max(No) from calidad3.usrno;";
   

    ResultSet rsxx;
try{
          Statement st = cnni.getConnection().createStatement();
         
                  rsxx=st.executeQuery(compli);
     
                  while(rsxx.next()){
                   int preusuario
                           =rsxx.getInt(1);
                   usuario=preusuario+1;
                   user();

/////////en una tabla guardo numeros incrementales selecciono el maximo
//y lo asigno para crear tablas con nombre dinamico es decir todas las tablas q creo generaran tablas
///dependiendo del numero de conexion q sea ejemplo usuario=1 hago mi sentencia sql de esta manera.
////"create table x"+usuario+"......"
////de esta manera m aseguro q si se conecta otro cliente no creara tablas intermedias con el mismo
////nombre
                                                                   
    }
}catch(SQLException e)
        {
                        System.out.println("Error: " + e.getMessage());
                        JOptionPane.showMessageDialog(null,"Error seleccionando \n usuario");
                        cnni.desconectar();
        }
 
/////////////////////////////////////////
                   String complj="insert into calidad3.usrno values("+usuario+");";

try{
          Statement stj = cnni.getConnection().createStatement();

                  stj.executeUpdate(complj);
JOptionPane.showMessageDialog(null,"..."+usuario);
}catch(SQLException e)
        {
                        System.out.println("Error: " + e.getMessage());
                        JOptionPane.showMessageDialog(null,"Error creando la tablainsertando \n numero usuario");
                        cnni.desconectar();
        }
    ///////////////////////////////////////
      boolean confirmacion2=false;
      //JOptionPane.showMessageDialog(null,"Hola mundo 1");
      String compl1,query;

      conect cnn = new conect();
 
    compl1="CREATE TABLE auxg"+usuario+" AS SELECT * FROM garantias WHERE "+cadgaranti+" ;";
    //JOptionPane.showMessageDialog(null,"cadena garantias"+compl1);
    ResultSet rs;
try{
          Statement st = cnn.getConnection().createStatement();
         
                  st.executeUpdate(compl1);
         
       //  JOptionPane.showMessageDialog(null,"creada ventas");
         

}catch(SQLException e)
        {
                        System.out.println("Error: " + e.getMessage());
                        JOptionPane.showMessageDialog(null,"Error creando la tabla \n intermedia auxg");
                        cnn.desconectar();
        }
 /////////////creando las tablas finales para las operaciones
/*
 SELECT MIS, mes, Count(NetClaimCount) AS totalw
FROM auxg
GROUP BY DATOS.MIS, DATOS.MOP;
 *
 */

       /////tabla garantias

 query="CREATE TABLE endwarranty"+usuario+" AS select MIS,count(NetClaimCount)AS totalw ,CONCAT (left(ProductionDate,2), right (ProductionDate,5)) AS mes "
 +"from auxg"+usuario+" where NetClaimCount=1 group by MIS,mes order BY MIS asc;";
 try{
          Statement st2 = cnn.getConnection().createStatement();
         
                  st2.executeUpdate(query);
       
         //JOptionPane.showMessageDialog(null,"tabla semi-final completa");

 }catch(SQLException e)
        {
                         System.out.println("Error: " + e.getMessage());
                         JOptionPane.showMessageDialog(null,"Error creando la tabla \n intermedia endwarranty");
                         cnn.desconectar();
        }
/////fin tabla garantias
 ////////////fin creando tablas finales

 conect cnn3 = new conect();

 try{
          Statement st3 = cnn3.getConnection().createStatement();
         
                  st3.executeUpdate("DROP TABLE auxg"+usuario+";");

 }catch(SQLException e)
        {
                        System.out.println("Error: " + e.getMessage());
                        JOptionPane.showMessageDialog(null,"Error eliminando \n tabla auxg");
                        cnn.desconectar();
        }

 
 ////////////////////comenzando operaciones
 ////////////////////para realizar tabla cruzada

String crear;

crear="create TABLE croswarran"+usuario+" (ID int Primary key not null auto_increment,MIS int );";
 try{
          Statement st5 = cnn3.getConnection().createStatement();

          st5.executeUpdate(crear);
       
          //JOptionPane.showMessageDialog(null,"creada cross warran solo id");

 }catch(SQLException e)
        {
                        System.out.println("Error: " + e.getMessage());
                        JOptionPane.showMessageDialog(null,"Error creando la tabla \n cruzada croswarran ");
                         cnn.desconectar();
        }
}///fin metodo op garantias

//////aqui otro metodo con las misma mecanica pero para otra tabla
////....
//////....

}/ fin clase calcpoints

</pre>

Como pueden ver creo varias tablas intermedias y con esa manera de asignarles un nombre dinamico, ya no tengo problema de q el cliente 1 creo una tabla y el cliente 2 la kiere crear entonces da error.

Lo q sucede es q cliente 1 y cliente 2 estan conectados quieren generar una grafica, la peticion que llegue al final del servlet es la unica que se completa.

las demas m botan el siguiente error.

Table 'croswarran37' already exists

aun q no esten creadas, al finalizar toda mi clase calcpionts elimino las tablas intermedias creadas

entonces creo q es un problema con los request pero ya acomode el inicio de sesion en varias partes y nada, asi q estoy algo desesperado.

Espero puedan ayudarme y espero no aburrirlos con tanto codigo, y es algo dificil de explicar por que tengo como 5000 lineas de codigo en unos 5 servlets y unas 4 clases.

cabe mencionar que la conexion a la bd durante todo el proceso siempre es con un mismo usuario.

asi se conecte un el cliente1 o el cliente2, etc., al servlet

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de skuarch

Sugerencia

para que tu codigo se entienda mas ponle las etiquetas < code > < /code > o < pre > < /pre >

Imagen de ezamudio

estado

Tal parece que estás guardando estado en tu servlet, por las variables de instancia que definiste, como user y que usas más abajo.

Tienes revueltos algunos conceptos:

la aplicacion funciona muy bien con solo una ejecucion, es decir pongo mi aplicacion en el servidor tomcat, y sucede algo raro el cliente1 accesa a la aplicacion y la ejecuta, ,el proceso comienza normalmente pero llega el cliente2 y ejecuta la aplicacion, entonces el servidor deja de realizar la peticion del cliente1 y comienza a realizar la peticion del cliente2, ya puse manejo de sesiones...

El cliente1 no accesa a la aplicación y la ejecuta. Suena muy pedante pero el uso correcto de la terminología ayuda a que tengas bien aterrizado el concepto de lo que realmente ocurre. Esto no es una aplicación como un programa que corres en tu escritorio, en tu IDE y que ejecutas al oprimir un botón o dar doble click en un icono. En este caso tienes un contenedor de servlets, Tomcat, en el cual hospedas el servlet que nos muestras (el cual reside dentro de una aplicación y se configura el acceso con el web.xml etc).

Tomcat va a tener una sola instancia de tu servlet. A esa instancia le va a enviar todas las peticiones que reciba.

El cliente1 envía una petición a Tomcat, quien se la pasa al servlet y ahí se ejecuta tu código y usas las variables de instancia en el método. Al final cuando el cliente1 obtiene una respuesta, el servlet se quedó con las variables de instancia como las haya dejado esa invocación del processRequest(). Así que cuando cliente2 entra, puede que no funcione bien el servlet porque ya tiene algunos valores que quedaron de la primera invocación que hizo cliente1. Y peor aún, si cliente1 y cliente2 invocan el servlet de manera simultánea, va a quedar el estado del servlet todo batido.

Por eso los servlets deben ser stateless, no deben guardar estado, es decir no deben usar variables de instancia para almacenar valores que sean pertinentes solamente para la petición que están procesando. Es un típico error cuando comienzas a hacer aplicaciones web porque en tus pruebas sale muy bien todo porque solamente hay un usuario concurrente (tú).

La manera más rápida y sencilla de arreglar esto es que todas esas variables de instancia las pases adentro de los métodos que las usan, para que existan de manera independiente para cada invocación del método. Y si alguna la pusiste como variable de instancia porque más de un método la usa, lo que debes hacer es pasar ese valor como parámetro a todos los métodos que la necesiten (y si es modificada necesitas devolver el valor al final del método y si estás leyendo y modificando varios valores entonces considera usar un VO, Value Object, un objeto que sí tiene variables de instancia que puedes modificar pero del cual vas a crear una instancia en cada invocación del servlet).

gracias!!!

Bueno gracias por leerme, estuve realizando alguunas modificaciones y creo q ya casi esta, tomare en uenta tus comentarios y t cuento q tal m va ezamudio.

Lo he solucionado!!!

Bueno si a alguien le importa o le sive de algo solo le tuve q agregar la palabra synchronized a los metodos de esta manera indico que solo es accesible una vez el metodo, y asi quedo solucionado.

seria algo asi:

synchronized public void {
.........................

}

Espero y le sirva a alguien.

Imagen de ezamudio

no es la solución

Espero y le sirva a alguien.

Espero que no llegue alguien igual de perdido y use esa "receta" como solución. Lo único que hiciste fue serializar todas las peticiones a la página, de modo que solamente se atiende una a la vez, y de hecho no resolviste el problema de que tu componente guarda estado; puede seguir dando resultados inconsistentes dependiendo cómo se use, si una petición comienza con el componente en el estado en que lo dejó la petición anterior.

serializar -> sincronizar

La palabra serializar es correcta y describe lo que hizo, aunque en este contexto sería mejor decir sincronizar.