Este método lança
java.lang.IllegalStateException: Não é possível encaminhar após a confirmação da resposta
e não consigo identificar o problema. Qualquer ajuda?
int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
String chkboxVal = "";
// String FormatId=null;
Vector vRow = new Vector();
Vector vRow1 = new Vector();
String GroupId = "";
String GroupDesc = "";
for (int i = 0; i < noOfRows; i++) {
if ((request.getParameter("chk_select" + i)) == null) {
chkboxVal = "notticked";
} else {
chkboxVal = request.getParameter("chk_select" + i);
if (chkboxVal.equals("ticked")) {
fwdurl = "true";
Statement st1 = con.createStatement();
GroupId = request.getParameter("GroupId" + i);
GroupDesc = request.getParameter("GroupDesc" + i);
ResultSet rs1 = st1
.executeQuery("select FileId,Description from cs2k_Files "
+ " where FileId like 'M%' and co_code = "
+ ccode);
ResultSetMetaData rsm = rs1.getMetaData();
int cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol1 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol1.addElement(rs1.getObject(j));
}
vRow.addElement(vCol1);
}
rs1 = st1
.executeQuery("select FileId,NotAllowed from cs2kGroupSub "
+ " where FileId like 'M%' and GroupId = '"
+ GroupId + "'" + " and co_code = " + ccode);
rsm = rs1.getMetaData();
cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol2 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol2.addElement(rs1.getObject(j));
}
vRow1.addElement(vCol2);
}
// throw new Exception("test");
break;
}
}
}
if (fwdurl.equals("true")) {
// throw new Exception("test");
// response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
request.setAttribute("GroupId", GroupId);
request.setAttribute("GroupDesc", GroupDesc);
request.setAttribute("vRow", vRow);
request.setAttribute("vRow1", vRow1);
getServletConfig().getServletContext().getRequestDispatcher(
"/GroupCopiedUpdt.jsp").forward(request, response);
}
servlets
response
illegalstateexception
forward
requestdispatcher
sansknwoledge
fonte
fonte
Respostas:
Um mal-entendido comum entre os iniciantes é que eles pensam que a chamada de a
forward()
,sendRedirect()
ousendError()
iria sair magicamente e "pular" para fora do bloco de método, ignorando assim o resto do código. Por exemplo:Portanto, isso não é verdade. Eles certamente não se comportam de maneira diferente de quaisquer outros métodos Java (espere, é
System#exit()
claro). Quando osomeCondition
exemplo acima étrue
e você está chamandoforward()
depoissendRedirect()
ousendError()
na mesma solicitação / resposta, então a chance é grande de que você obtenha a exceção:Se a
if
instrução chamar aforward()
e você depois chamarsendRedirect()
ousendError()
, a exceção abaixo será lançada:Para corrigir isso, você precisa adicionar uma
return;
declaração depois... ou para introduzir um bloco else.
Para Naildown a causa raiz em seu código, basta procurar por qualquer linha que chama uma
forward()
,sendRedirect()
ousendError()
sem sair do bloco de método ou pular o resto do código. Isso pode estar dentro do mesmo servlet antes da linha de código específica, mas também em qualquer servlet ou filtro que foi chamado antes do servlet específico.No caso de
sendError()
, se o seu único propósito é definir o status da resposta, usesetStatus()
.Outra causa provável é que o servlet grava na resposta enquanto um
forward()
será chamado ou foi chamado no mesmo método.O tamanho padrão do buffer de resposta na maioria dos servidores é 2 KB, portanto, se você gravar mais de 2 KB nele, ele será confirmado e
forward()
falhará da mesma maneira:A solução é óbvia, apenas não escreva para a resposta no servlet. Isso é responsabilidade do JSP. Você apenas define um atributo de solicitação como tal
request.setAttribute("data", "some string")
e, em seguida, imprime em JSP dessa forma${data}
. Veja também nossa página wiki Servlets para aprender como usar Servlets da maneira certa.Outra causa provável é que o servlet grava um download de arquivo na resposta após o qual, por exemplo, a
forward()
é chamado.Isso não é tecnicamente possível. Você precisa remover a
forward()
chamada. O usuário final permanecerá na página aberta no momento. Se você realmente pretende alterar a página após o download de um arquivo, será necessário mover a lógica de download do arquivo para o carregamento da página da página de destino.Ainda outra causa provável é que os métodos
forward()
,sendRedirect()
ousendError()
são invocados via código Java embutido em um arquivo JSP na forma antiga<% scriptlets %>
, uma prática que foi oficialmente desencorajada desde 2001 . Por exemplo:O problema aqui é que o JSP grava internamente imediatamente o texto do modelo (ou seja, código HTML)
out.write("<!DOCTYPE html> ... etc ...")
assim que é encontrado. Este é, portanto, essencialmente o mesmo problema explicado na seção anterior.A solução é óbvia, apenas não escreva código Java em um arquivo JSP. Essa é a responsabilidade de uma classe Java normal, como um Servlet ou um Filtro. Veja também nossa página wiki Servlets para aprender como usar Servlets da maneira certa.
Veja também:
Não relacionado ao seu problema concreto, seu código JDBC está perdendo recursos. Corrija isso também. Para obter dicas, consulte também Com que frequência Connection, Statement e ResultSet devem ser fechados no JDBC?
fonte
break;
? Isso significaria que o código estava dentro de algumfor
ouwhile
loop em queforward()
foi chamado repetidamente durante o loop (o que é, portanto, incorreto, você deve chamar o encaminhamento apenas uma vez APÓS o loop --ou para se livrar do loop, pois aparentemente não é necessário) .forward()
chamada, mas não deveria. O JSF, com o qual estou familiarizado, também faz isso, a menos que você chame explicitamenteFacesContext#responseComplete()
. Esta pergunta relacionada (que encontrei usando as palavras-chave "grails prevent render response") pode ser útil: stackoverflow.com/questions/5708654/…forward()
chamada, mas não deveria estar fazendo isso. A solução é funcionalmente óbvia: diga a ele para não fazer isso. Ele não fazia ideia de que você assumiu programaticamente o trabalho que Grails deveria fazer: lidar com a resposta. Tecnicamente, não tenho ideia de como dizer isso a Grails. Mas eu sei que muitos outros frameworks MVC suportam isso (sendo instruídos a não lidar com a resposta por si só), como JSF, Spring MVC, Wicket, etc. Eu ficaria surpreso se isso fosse impossível em Grails.até mesmo adicionar uma instrução de retorno traz essa exceção, para a qual a única solução é este código:
fonte
Normalmente, você vê esse erro depois de já ter feito um redirecionamento e, em seguida, tentar enviar mais alguns dados para o fluxo de saída. Nos casos em que já vi isso, geralmente é um dos filtros que está tentando redirecionar a página e, em seguida, ainda encaminha para o servlet. Não consigo ver nada de errado com o servlet, então você pode tentar dar uma olhada em todos os filtros que você tem no lugar também.
Edit : Um pouco mais de ajuda no diagnóstico do problema ...
A primeira etapa para diagnosticar esse problema é verificar exatamente onde a exceção está sendo lançada. Estamos assumindo que está sendo jogado pela linha
Mas você pode descobrir que ele está sendo lançado posteriormente no código, onde está tentando enviar para o fluxo de saída depois de tentar fazer o encaminhamento. Se vier da linha acima, significa que em algum lugar antes dessa linha você tem:
Boa sorte!
fonte
Isso ocorre porque seu servlet está tentando acessar um objeto de solicitação que não existe mais. A instrução de encaminhamento ou inclusão de um servlet não interrompe a execução do bloco de método. Ele continua até o final do bloco de método ou primeira instrução de retorno, como qualquer outro método java.
A melhor maneira de resolver este problema é definir a página (onde você supõe que irá encaminhar a solicitação) dinamicamente de acordo com sua lógica. Isso é:
e fazer o encaminhamento apenas uma vez na última linha ...
você também pode corrigir esse problema usando a instrução return após cada forward () ou colocar cada forward () no bloco if ... else
fonte
Eu removi
Então funcionou bem para mim
fonte
Colisão...
Eu apenas tive o mesmo erro. Percebi que estava invocando
super.doPost(request, response);
ao substituir odoPost()
método, bem como invocando explicitamente o construtor da superclasseAssim que comentei a declaração
super.doPost(request, response);
internadoPost()
funcionou perfeitamente ...Desnecessário dizer que preciso reler as
super()
práticas recomendadas: pfonte
Você deve adicionar a instrução de retorno enquanto estiver encaminhando ou redirecionando o fluxo.
Exemplo:
se forwardind,
se redirecionando,
fonte
Após o método return forward, você pode simplesmente fazer isso:
Isso quebrará o escopo atual.
fonte