Coloque a classe servlet em um package
Em primeiro lugar, coloque a classe servlet em um Java package
. Você deve sempre colocar classes Java reutilizáveis publicamente em um pacote, caso contrário, elas são invisíveis para as classes que estão em um pacote, como o próprio servidor. Dessa forma, você elimina possíveis problemas específicos do ambiente. Servlets sem pacote funcionam apenas em combinações específicas de Tomcat + JDK e nunca se deve confiar nisso.
No caso de um projeto IDE "simples", a classe precisa ser colocada em sua estrutura de pacote dentro da pasta "Recursos Java" e, portanto, não "Conteúdo da Web", isto é para arquivos da web como JSP. Abaixo está um exemplo da estrutura de pastas de um projeto da Web dinâmico Eclipse padrão , conforme visto na visualização do Navegador :
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
No caso de um projeto Maven, a classe precisa ser colocada em sua estrutura de pacote dentro main/java
e, portanto, nãomain/resources
, por exemplo , isso é para arquivos não pertencentes à classe . Abaixo está um exemplo da estrutura de pastas de um projeto Maven webapp padrão, conforme visto na visualização Navigator do Eclipse :
MavenProjectName
|-- src
| `-- main
| |-- java
| | `-- com
| | `-- example
| | `-- YourServlet.java
| |-- resources
| `-- webapp
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
Observe que a /jsps
subpasta não é estritamente necessária. Você pode até mesmo prescindir dele e colocar o arquivo JSP diretamente na raiz webcontent / webapp, mas estou apenas retomando sua pergunta.
Definir o URL do servlet em url-pattern
O URL do servlet é especificado como o "padrão de URL" do mapeamento do servlet. Não é absolutamente por definição o nome da classe / nome do arquivo da classe servlet. O padrão de URL deve ser especificado como valor de @WebServlet
anotação.
package com.example; // Use a package!
@WebServlet("/servlet") // This is the URL of the servlet.
public class YourServlet extends HttpServlet { // Must be public and extend HttpServlet.
// ...
}
Caso queira oferecer suporte a parâmetros de caminho como /servlet/foo/bar
, use um padrão de URL de /servlet/*
. Veja também Servlet e parâmetros de caminho como / xyz / {value} / test, como mapear em web.xml?
@WebServlet
funciona apenas no Servlet 3.0 ou mais recente
Para usar @WebServlet
, você só precisa se certificar de que seu web.xml
arquivo, se houver (é opcional desde o Servlet 3.0), é declarado conforme a versão Servlet 3.0+ e, portanto, não conforme, por exemplo, versão 2.5 ou inferior . Abaixo está um Servlet 4.0 compatível (que combina com Tomcat 9+, WildFly 11+, Payara 5+, etc).
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
>
<!-- Config here. -->
</web-app>
Ou, caso você ainda não esteja no Servlet 3.0+ (por exemplo, Tomcat 6 ou mais antigo), remova a @WebServlet
anotação.
package com.example;
public class YourServlet extends HttpServlet {
// ...
}
E registre o servlet web.xml
assim:
<servlet>
<servlet-name>yourServlet</servlet-name>
<servlet-class>com.example.YourServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>yourServlet</servlet-name>
<url-pattern>/servlet</url-pattern> <!-- This is the URL of the servlet. -->
</servlet-mapping>
Observe, portanto, que você não deve usar as duas maneiras. Use configuração baseada em anotação ou configuração baseada em XML. Quando você tiver ambos, a configuração baseada em XML substituirá a configuração baseada em anotação.
Verificando a construção / implantação
Caso você esteja usando uma ferramenta de construção como Eclipse e / ou Maven, você precisa ter certeza absoluta de que o arquivo de classe do servlet compilado reside em sua estrutura de pacote na /WEB-INF/classes
pasta do arquivo WAR produzido. No caso de package com.example; public class YourServlet
, deve estar localizado em /WEB-INF/classes/com/example/YourServlet.class
. Caso contrário, você enfrentará no caso de @WebServlet
também um erro 404, ou no caso de <servlet>
um erro HTTP 500 como abaixo:
HTTP Status 500
Erro ao instanciar a classe de servlet com.example.YourServlet
E localize no log do servidor a java.lang.ClassNotFoundException: com.example.YourServlet
, seguido por a java.lang.NoClassDefFoundError: com.example.YourServlet
, por sua vez seguido por javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
.
Uma maneira fácil de verificar se o servlet está compilado corretamente e colocado no classpath é permitir que a ferramenta de construção produza um arquivo WAR (por exemplo, clique com o botão direito do mouse em projeto, Exportar> arquivo WAR no Eclipse) e inspecione seu conteúdo com uma ferramenta ZIP. Se a classe do servlet estiver ausente /WEB-INF/classes
ou se a exportação causar um erro, o projeto está mal configurado ou alguns padrões de configuração do IDE / projeto foram revertidos por engano (por exemplo, Projeto> Compilar automaticamente foi desativado no Eclipse).
Você também precisa se certificar de que o ícone do projeto não tem uma cruz vermelha indicando um erro de construção. Você pode encontrar o erro exato na visualização Problemas ( Janela> Mostrar Visualização> Outro ... ). Normalmente, a mensagem de erro é boa Googlable. Caso você não tenha ideia, o melhor é reiniciar do zero e não tocar em nenhum padrão de configuração de IDE / projeto. Caso esteja usando o Eclipse, você pode encontrar instruções em Como faço para importar a API javax.servlet no meu projeto Eclipse?
Testando o servlet individualmente
Contanto que o servidor seja executado localhost:8080
e o WAR seja implantado com sucesso em um caminho de contexto /contextname
(cujo padrão é o nome do projeto IDE, diferencia maiúsculas de minúsculas!) E o servlet não falhou em sua inicialização (leia os logs do servidor para qualquer implantação / mensagens de sucesso / falha do servlet e o caminho de contexto real e mapeamento do servlet), então um servlet com padrão de URL de /servlet
está disponível em http://localhost:8080/contextname/servlet
.
Você pode simplesmente inseri-lo diretamente na barra de endereços do navegador para testá-lo individualmente. Se doGet()
for substituído e implementado corretamente, você verá sua saída no navegador. Ou se você não tiver nenhum doGet()
ou se ele chamar incorretamente super.doGet()
, um erro " HTTP 405: o método HTTP GET não é compatível com este URL " será mostrado (que ainda é melhor do que um 404, pois um 405 é uma evidência de que o servlet se é realmente encontrado).
Substituir service()
é uma prática ruim, a menos que você esteja reinventando uma estrutura MVC - o que é muito improvável se você está apenas começando com servlets e não tem noção do problema descrito na pergunta atual;) Consulte também Aplicativos baseados na web de Padrões de Design .
Independentemente disso, se o servlet já retorna 404 quando testado individualmente, então é totalmente inútil tentar com um formulário HTML. Logicamente, portanto, também é totalmente inútil incluir qualquer formulário HTML em perguntas sobre erros 404 de um servlet.
Referência ao URL do servlet em HTML
Depois de verificar se o servlet funciona bem quando invocado individualmente, você pode avançar para o HTML. Quanto ao seu problema concreto com o formulário HTML, o <form action>
valor precisa ser um URL válido. O mesmo se aplica a <a href>
. Você precisa entender como funcionam os URLs absolutos / relativos. Você sabe, um URL é um endereço da web que você pode inserir / ver na barra de endereços do navegador. Se você estiver especificando uma URL relativa como ação de formulário, ou seja, sem o http://
esquema, ela se tornará relativa à URL atual, conforme você vê na barra de endereços do navegador. Portanto, não é absolutamente relativo à localização do arquivo JSP / HTML na estrutura de pastas WAR do servidor, como muitos iniciantes parecem pensar.
Portanto, supondo que a página JSP com o formulário HTML seja aberta por http://localhost:8080/contextname/jsps/page.jsp
e você precise enviar a um servlet localizado em http://localhost:8080/contextname/servlet
, aqui estão vários casos (observe que você pode substituir <form action>
com segurança por <a href>
aqui):
A ação do formulário é enviada para um URL com uma barra inicial.
<form action="/servlet">
A barra inicial /
torna o URL relativo ao domínio, portanto, o formulário será enviado para
http://localhost:8080/servlet
Mas isso provavelmente resultará em um 404, pois está no contexto errado.
A ação do formulário é enviada para um URL sem uma barra inicial.
<form action="servlet">
Isso torna o URL relativo à pasta atual do URL atual, portanto, o formulário será enviado para
http://localhost:8080/contextname/jsps/servlet
Mas isso provavelmente resultará em um 404, pois está na pasta errada.
A ação do formulário é submetida a um URL que sobe uma pasta.
<form action="../servlet">
Isso irá subir uma pasta (exatamente como nos caminhos do sistema de arquivos do disco local!), Portanto, o formulário será enviado para
http://localhost:8080/contextname/servlet
Este deve funcionar!
A abordagem canônica, entretanto, é tornar a URL relativa ao domínio, para que você não precise corrigir as URLs novamente quando mover os arquivos JSP para outra pasta.
<form action="${pageContext.request.contextPath}/servlet">
Isso vai gerar
<form action="/contextname/servlet">
Que, portanto, sempre enviará para o URL correto.
Use aspas retas em HTML
Você precisa ter certeza absoluta de que está usando aspas retas em atributos HTML como action="..."
ou action='...'
e, portanto, não aspas curvas como action=”...”
ou action=’...’
. Aspas curtas não são suportadas em HTML e simplesmente se tornarão parte do valor.
Veja também:
Outros casos de erro HTTP Status 404:
Cenário # 1: você acidentalmente reimplantou a partir da linha de comando enquanto o tomcat já estava em execução .
Resposta curta: pare o Tomcat, exclua a pasta de destino , o pacote mvn e reimplante
Cenário 2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME .jsp")
Resposta curta: Verifique a ortografia do nome do arquivo , certifique-se de que a caixa está correta.
Cenário # 3: exceções de classe não encontrada (resposta colocada aqui porque: Pergunta # 17982240) ( java.lang.ClassNotFoundException para servlet em tomcat com eclipse ) (foi marcado como duplicado e me direcionou aqui)
Resposta curta nº 3.1: web.xml tem caminho de pacote incorreto na tag da classe de servlet.
Resposta curta # 3.2: o arquivo java tem uma declaração de importação errada.
Abaixo estão mais detalhes para o Cenário # 1:
1: Pare o Tomcat
2: Exclua a pasta "destino". (mvn clean não vai te ajudar aqui)
3: pacote mvn
4: YOUR_DEPLOYMENT_COMMAND_HERE
(Meu: java -jar target / dependency / webapp-runner.jar --port 5190 target / *. War)
História Completa:
Abri acidentalmente uma nova janela git-bash e tentei implantar um arquivo .war para meu projeto heroku via:
java -jar target / dependency / webapp-runner.jar --port 5190 target / *. war
Depois de uma falha na implantação, percebi que havia duas janelas git-bash abertas e não usei CTLR + C para interromper a implantação anterior .
Encontrei-me com:
Abaixo estão mais detalhes para o Cenário # 3:
CENÁRIO 3.1: O caminho do pacote da classe de servlet está errado em seu arquivo web.xml.
Ele deve CORRESPONDER à instrução do pacote no topo de sua classe de servlet java.
Arquivo: my_stuff / MyClass.java :
Arquivo: PRJ_ROOT / src / main / webapp / WEB-INF / web.xml
CENÁRIO 3.2:
Você colocou a instrução " pacote " errada no topo do seu arquivo myClass.java.
Por exemplo:
O arquivo está em: pasta " / my_stuff "
Você escreveu por engano:
Isso é complicado porque:
1: A compilação maven (pacote mvn) não relatará erros aqui.
2: a linha da classe de servlet em web.xml pode ter um caminho de pacote CORRETO. Por exemplo:
Pilha usada: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :
fonte
Solução para
HTTP Status 404
no NetBeans IDE: Clique com o botão direito do mouse em seu projeto e vá para as propriedades do projeto, clique em executar e insira o URL relativo do projeto comoindex.jsp
.fonte
Meu problema era que meu método não tinha a anotação @RequestBody. Depois de adicionar a anotação, não recebi mais a exceção 404.
fonte
Execute as duas etapas a seguir. Espero que isso resolva o problema "404 não encontrado" no servidor tomcat durante o desenvolvimento do aplicativo servlet java.
Passo 1:
Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server
Passo 2:
Double Click on the server(in the server explorer tab)->Select Use tomcat installation option inside server location menu
fonte
Removi a antiga biblioteca da web, que são bibliotecas do Spring Framework. E construir um novo caminho para as bibliotecas. Então funciona.
fonte
Um tópico antigo, mas como não o encontrei em outro lugar, aqui está mais uma possibilidade:
Se você estiver usando servlet-api 3.0+ , seu web.xml NÃO deve incluir o
metadata-complete="true"
atributoIsso informa ao tomcat para mapear os servlets usando dados fornecidos em
web.xml
vez de usar a@WebServlet
anotação.fonte
Em primeiro lugar, execute seu IDE como Admin. Depois disso, clique com o botão direito na pasta do projeto -> Aspectos do projeto e certifique-se de que a versão do Java esteja configurada corretamente. No meu PC. (Por exemplo 1.8) Agora deve funcionar.
Não inicie apenas o seu servidor, por exemplo Wildfly, usando o cmd. Ele deve ser iniciado dentro do IDE e agora visitar a URL do seu host local. Exemplo: http: // localhost: 8080 / HelloWorldServlet / HelloWorld
fonte
A correção que funcionou para mim é (se você estiver usando Maven): Clique com o botão direito do mouse em seu projeto, Maven -> Atualizar projeto. Isso pode dar a você algum outro erro com o JDK e outras bibliotecas (no meu caso, o conector MySQL), mas depois de corrigi-los, seu problema original deve ser corrigido!
fonte
Se você gostaria de abrir um servlet com javascript sem usar o 'formulário' e o botão 'enviar', aqui está o seguinte código:
Chave:
1) button-id: A tag 'id' que você atribui ao seu botão em seu arquivo html / jsp.
2) full-servlet-path: o caminho que é mostrado no navegador quando você executa o servlet sozinho
fonte
Mapeamento em web.xml é o que eu fiz: -
packagename.filename entre a abertura e o fechamento da tag servlet-class no arquivo xml.
Ambos os métodos não funcionam um com o outro, então ou eu uso o método de anotação dos arquivos mencionados quando criamos o servlet ou a forma de mapeamento, então excluo ou comento a linha de anotação. Por exemplo:
Comentando a linha de anotação de código no respectivo arquivo, caso o mapeamento em xml seja feito.
fonte
Verifique se a raiz de contexto não pode estar vazia .
Se você estiver usando o eclipse:
clique com o botão direito , selecione propriedades e , em seguida , configurações do projeto da web . Verifique a raiz de contexto não pode estar vazio
fonte