Crazy God Javaweb versão completa introdução básica (versão IDEA) Tutorial JavaWeb que vale a pena aprender

Web Java

Web Java

1. Conceitos básicos

desenvolvimento web:

  • web, significando página da web, www.baidu.com
  • web estática
    • HTML, CSS
    • Os dados disponíveis para todos verem nunca mudam!
  • web dinâmica
    • Taobao, quase todos os sites
    • Os dados fornecidos a todos sempre mudarão. Cada pessoa vê informações diferentes em momentos e lugares diferentes.
    • Pilha de tecnologia: Servlet/Jsp, ASP, PHP

Em Java, a tecnologia para desenvolvimento dinâmico de recursos da Web é chamada coletivamente de JavaWeb;

1.2. Aplicativo Web

aplicativo da web: um programa que fornece acesso do navegador a:

  • a.html, b.html... vários recursos da Web. Esses recursos da Web podem ser acessados ​​pelo mundo exterior e fornecer serviços ao mundo exterior.
  • Cada página e recurso que pode ser acessado existe em um computador em um determinado local.
  • URL
  • Este recurso da web unificado será colocado na mesma pasta, aplicativo da web–> Tomcat: servidor
  • Um aplicativo da web consiste em várias partes (web estática, web dinâmica)
    • html, css, js
    • jsp, servlet
    • programa java
    • pacote jar
    • Arquivo de configuração (Propriedades)

Após a aplicação web ser escrita, se você quiser fornecê-la para acesso externo: é necessário um servidor para gerenciamento unificado;

1.3. Teia estática

  • *.htm, *.html Estes são os sufixos das páginas da Web. Se essas coisas sempre existirem no servidor, podemos lê-las diretamente.

Adicione a descrição da imagem

  • Desvantagens da web estática
    • A página da web não pode ser atualizada dinamicamente e todos os usuários veem a mesma página.
      • Imagem carrossel, clique em efeitos especiais: pseudo-dinâmico
      • JavaScript [mais comumente usado no desenvolvimento real
      • VBScript
    • Ele não pode interagir com os dados (os dados não podem ser persistidos e os usuários não podem interagir)

1.4. Web dinâmica

A página será exibida de forma dinâmica: “O efeito de exibição da página web varia de pessoa para pessoa”;

Insira a descrição da imagem aqui

deficiência

  • Ocorreu um erro ao adicionar recursos dinâmicos da Web ao servidor. Precisamos reescrever o programa em segundo plano e publicá-lo novamente.
    • Manutenção de tempo de inatividade

vantagem:

  • As páginas da Web podem ser atualizadas dinamicamente, para que todos os usuários não vejam a mesma página.
  • Ele pode interagir com os dados (persistência de dados: registro, informações do produto, informações do usuário)

Insira a descrição da imagem aqui

2. servidor web

ASP

  • Microsoft: ASP é o mais popular na China
  • Incorporar script VB em HTML, ASP + COM
  • No desenvolvimento ASP, basicamente cada página possui milhares de linhas de código comercial e a página é extremamente confusa.
  • Altos custos de manutenção
  • C#
  • IIS
<h1>
    <h1>
        <%
        System.out.println("hello")
        %>
    </h1>
</h1> 

php

  • O desenvolvimento de PHP é rápido, poderoso, multiplataforma e o código é simples (70%, WP)
  • Incapaz de transportar grandes quantidades de tráfego (limitações)

JSP/Serviço

B/S: navegador e servidor

C/S: cliente e servidor

  • A arquitetura B/S promovida principalmente pela Sun Company
  • Baseado na linguagem Java (todas as grandes empresas, ou alguns componentes de código aberto, são escritos em Java)
  • Pode suportar o impacto de três grandes problemas (alta simultaneidade, alta disponibilidade, alto desempenho)
  • Sintaxe como ASP, ASP–> JSP, fortalece a força do mercado

2.2. servidor web

O servidor é uma operação passiva, usada para processar algumas solicitações de usuários e fornecer algumas informações de resposta aos usuários:

IIS

Microsoft ASP… vem com Windows

gato

Tomcat é um projeto central do projeto Jakarta da Apache Software Foundation. Como o Tomcat tem tecnologia avançada, desempenho estável e é gratuito, ele é profundamente amado pelos entusiastas de Java e reconhecido por alguns desenvolvedores de software. Tornou-se um aplicativo da web relativamente popular servidor.

O servidor Tomcat é um servidor de aplicativos da Web de código aberto gratuito . É um servidor de aplicativos leve . É comumente usado em sistemas de pequeno e médio porte e situações onde não há muitos usuários de acesso simultâneo. É a primeira escolha para desenvolver e depurar JSP programas.

Na verdade, o Tomcat executa páginas JSP e Servlets, e a versão mais recente do Tomcat é 10.0.23**. **

Baixe o tomcat

  1. Instalação e descompressão
  2. Compreenda os arquivos de configuração e a estrutura de diretórios
  3. efeito

3、Tomcat

3.1. Instale o Tomcat

Site oficial: https://tomcat.apache.org

Insira a descrição da imagem aqui

3.2. Inicialização e configuração do Tomcat

Informações da pasta:
Insira a descrição da imagem aqui

Inicie o Tomcat

  • startup.bat inicia o servidor
  • shutdown.bat desliga o servidor

Visite o site: http://localhost:8080/

3.3. Configuração

Insira a descrição da imagem aqui

  • O número da porta do host pode ser configurado: número da porta padrão 8080
<Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

O nome do host pode ser configurado: o nome do host padrão é localhost e o local de armazenamento padrão do site é webapps

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

Questões de entrevista:

Como o site é acessado?

  1. Digite o nome do domínio e pressione Enter

  2. Verifique se existe este mapeamento de nome de domínio no arquivo de configuração "C:\Windows\System32\drivers\etc\hosts" desta máquina:

    • Se existir: retorne diretamente o endereço IP correspondente, neste endereço o programa web que precisamos acessar pode ser acessado diretamente.
    • Não: Vá até o servidor DNS para pesquisar e retorne se for encontrado. Se não for encontrado, retorne "Não encontrado".

imagem-20230203130342439

3.4. Publique um site

  • Coloque o site que você escreveu no diretório especificado no servidor (aplicativos da web, você pode acessá-lo
--webapps : Tomcat服务器的web目录
    -ROOT:
    -hwt:	网站的目录名
        -WEB-INF:
        	-classes:	Java程序
        	-lib:	web应用所依赖的jar包
			- web.xml:	网站的配置文件
		-index.html:	默认的首页
		-static:	
			-css
            -js
            -img

4.HTTP

4.1. O que é HTTP?

HTTP: (Hypertext Transfer Protocol) é um protocolo simples de solicitação-resposta, geralmente executado sobre TCP

  • Texto: html, string
  • Hipertexto: fotos, músicas, vídeos, posicionamento, mapas
  • porta 80

HTTPS: seguro

  • Porto: 443

4.2. Duas eras

  • HTTP1.0
    • Depois que o cliente se conecta ao servidor web, ele só pode obter um recurso.
  • HTTP2.0
    • Depois que o cliente se conecta ao servidor web, ele pode obter vários recursos da web

4.3. Solicitação HTTP

  • Cliente ---- Solicitação ------- Servidor

Baidu

Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 180.101.50.242:443
Referrer Policy: unsafe-url
1. Linha de solicitação
  • Método de solicitação na linha de solicitação: GET
  • Método de solicitação: Get, Post , HEAD, DELETE, PUT, TRACT
    • GET: A solicitação pode conter relativamente poucos parâmetros, o tamanho é limitado e o conteúdo dos dados será exibido na barra de endereços URL do navegador. Não é seguro, mas é eficiente;
    • POST: Não há limite de parâmetros que podem ser transportados e não há limite de tamanho. O conteúdo dos dados não será exibido na barra de endereço URL do navegador. É seguro e ineficiente.
2. Cabeçalho da mensagem
Accept: text/html	支持的数据类型
Accept-Encoding: gzip, deflate, br	支持的编码格式
Accept-Language: zh-CN,zh;q=0.9   语言环境
Cache-Control: max-age=0		缓存控制
Connection: keep-alive		告诉浏览器,请求完成是断开还是保持连接
HOST:主机

4.4. Resposta HTTP

  • Servidor-----Resposta------Cliente

Baidu

Bdpagetype: 1
Bdqid: 0x93f5dcf00001d517
Connection: keep-alive	连接
Content-Encoding: gzip	编码
Content-Type: text/html; 类型
1. Corpo de resposta
Accept: text/html	支持的数据类型
Accept-Encoding: gzip, deflate, br	支持的编码格式
Accept-Language: zh-CN,zh;q=0.9   语言环境
Cache-Control: max-age=0		缓存控制
Connection: keep-alive		告诉浏览器,请求完成是断开还是保持连接
HOST:主机
Refresh:告诉客户端,多久刷新一次
Location:让网页重新定位
2. Código de status de resposta
  • 200: Solicitação de resposta bem-sucedida 200

  • 3xx: Solicitar redirecionamento

    • Redirecionar para um novo URL
  • 4xx: Recurso não encontrado 404

    • O recurso não existe
  • 5xx: Código de erro do servidor 500 502: Erro de gateway

Perguntas comuns em entrevistas:

O que você experimentou quando a página foi exibida quando você digitou o endereço na barra de endereços do navegador e pressionou Enter?

5. especialista

O papel do especialista:

在Javaweb开发中,需要使用大量的jar包,只能手动导入,通过maven可以帮助我们自动导入jar包

5.1. Ferramenta de gerenciamento de arquitetura de projeto Maven

A ideia central do Maven: acordo é maior que configuração

  • Se houver restrições, não as viole

O Maven estipulará nossas especificações de código e devemos segui-las.

5.2. Baixe e instale o Maven

Site oficial: https://maven.apache.org/
Insira a descrição da imagem aqui

5.3. Configurar variáveis ​​de ambiente

  • M2_HOME: diretório bin no diretório maven
  • MAVEN_HOME: diretório maven
  • Configure %MAVEN_HOME%\bin no caminho do sistema

mvn -version testa se a instalação foi bem-sucedida

5.4. Configurar imagem do Alibaba Cloud

  • Espelhos: espelhos
    • Função: Acelerar o download
  • Geralmente use a imagem do Alibaba Cloud
<mirror>
     <id>nexus-aliyun</id>
     <mirrorOf>*</mirrorOf>
     <name>Nexus aliyun</name>
     <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

5.5. Armazém local

**Crie um repositório local: **localRepository

<localRepository>D:\environment\java\apache-maven-3.8.7\maven-repo</localRepository>

5.6. Usando maven no IDEA

  1. Iniciar IDEIA

  2. Crie um projeto web maven

Insira a descrição da imagem aqui

  1. Inicialização do projeto bem-sucedida
    Insira a descrição da imagem aqui

  2. Observe as mudanças no repositório maven

  3. Configurações do Maven no IDEA

    Verifique a configuração do Maven após a criação bem-sucedida
    Insira a descrição da imagem aqui

5.7. Crie um projeto Maven normal

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

Disponível apenas no aplicativo da web
Insira a descrição da imagem aqui

5.8. Configurar o Tomcat no IDEA

Insira a descrição da imagem aqui

Configuração necessária: Para acessar um site, você deve especificar o nome de uma pasta

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

5.9.arquivo pom

O arquivo pom.xml é o arquivo de configuração principal do Maven

<?xml version="1.0" encoding="UTF-8"?>
<!--pom文件的头文文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
<!--配置的GAV-->
  <groupId>org.example</groupId>
  <artifactId>javaweb-01-maven</artifactId>
  <version>1.0-SNAPSHOT</version>

  <packaging>war</packaging>
  <!--
    package项目的的包方式
    jar:Java应用
    war:Javaweb应用-->
  <name>javaweb-01-maven Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

<!--配置-->
  <properties>
<!--    项目默认构建编码-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--    编码的版本-->
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
<!--项目依赖-->
  <dependencies>
<!--    具体的依赖配置-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
<!--项目构建工具-->
  <build>
    <finalName>javaweb-01-maven</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Como a convenção do maven é maior que sua configuração, o arquivo de configuração que escrevemos pode não ter efeito. Solução:

<!--在build中配置resources,来防止资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

5.10. Importar dependências de pacotes

Insira a descrição da imagem aqui

endereço do armazém maven: https://mvnrepository.com/

5.10、web.xml

Substituir arquivo de cabeçalho

<?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"
  metadata-complete="true">
</web-app>

5.11. Uso do armazém Maven

endereço do armazém maven: https://mvnrepository.com/

6.Servlet

6.1. Introdução ao Servlet

  • Servlet é uma tecnologia usada pela Sun para desenvolver web dinâmica
  • A Sun fornece uma interface nessas APIs chamada: Servlet. Se você deseja desenvolver um programa Servlet, você só precisa concluir duas pequenas etapas:
    • Escreva uma classe para implementar a interface Servlet
    • Implante as classes Java desenvolvidas no servidor web

O programa Java que implementa a interface Servlet é chamado Servlet

6.2、HelloServlet

Interface de servlet A Sun possui duas classes de implementação padrão: HttpServlet,

  1. Construa um projeto Maven normal, exclua o diretório src interno e, em seguida, crie um modelo neste projeto; este projeto vazio é o projeto Maven principal;

  2. Compreensão dos projetos pai-filho Maven:

    O projeto pai terá

    <modules>
            <module>servlet-01</module>
    </modules>
    

    Haverá subprojetos

     <parent>
            <artifactId>javaweb-02-Servlet</artifactId>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
    </parent>
    

    Os subprojetos do pacote Jar no projeto pai podem ser usados ​​diretamente

  3. Otimização do ambiente Maven

    1. Modifique web.xml para ser o mais recente
    2. Conclua a estrutura do Maven
  4. Escreva um programa Servlet

    1. Escreva uma aula normal
    2. Implemente a interface Servlet e herde diretamente o HttpServlet

Insira a descrição da imagem aqui

public class HelloServlet extends HttpServlet {
    
    

    //由于get或者post只是请求实现方式的不同,可以互相调用,业务逻辑一样

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
//        ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();//响应流

        writer.print("hello Servlet!");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}
  1. Escrever mapeamento de servlet

    O programa é escrito em Java, mas precisa ser acessado através de um navegador. O navegador está conectado ao servidor web, portanto o Servlet precisa ser cadastrado no web service e um caminho de acesso deve ser fornecido.

    <!--    注册Servlet-->
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.hwt.servlet.HelloServlet</servlet-class>
        </servlet>
    <!--    Servlet的请求路径-->
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
  2. Configurar Tomecat

    Obs: Basta configurar o caminho para liberação do projeto.

  3. Comece a testar

Perceber:

  • Alternar /hello. Lu Jin relata o erro 500 e usa a versão Tomcat10. Isso pode ser resolvido mudando para o Tomcat9.
  • Código Qi℃伅 distorcido:
    • Abra a pasta conf/ logging.properties no diretório de instalação do Tomcat e modifique o arquivo logging.properties.
    • Altere java.util.logging.ConsoleHandler.encoding = utf-8
      para java.util.logging.ConsoleHandler.encoding = GBK

6.3. Princípio do servlet

O servlet é chamado pelo servidor Web. Após receber a solicitação do navegador, o servidor Web irá

Insira a descrição da imagem aqui

6.4. Problema de mapeamento

  1. Um Servlet pode especificar um caminho de mapeamento

      <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
      </servlet-mapping>
    
  2. Um Servlet pode especificar vários caminhos de mapeamento

<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping> 
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello1</url-pattern>
</servlet-mapping> 
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hell2</url-pattern>
</servlet-mapping>
  1. Um Sevlet pode especificar um caminho de mapeamento universal
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello/*</url-pattern>
</servlet-mapping> 
  1. Caminho de solicitação padrão: prioridade mais alta que index.jsp
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping> 
  1. Especifique alguns sufixos ou prefixos
<!--  可以自定义后缀实现请求映射
      注意,*前面不能加项目映射的路径
      hello/ssss.aaa-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.hwt</url-pattern>
  </servlet-mapping>
  1. O caminho de mapeamento inerente especificado tem a prioridade mais alta. Se não puder ser encontrado, a solicitação de processamento padrão será usada.

    <!--404-->
    <servlet>
      <servlet-name>error</servlet-name>
      <servlet-class>com.hwt.servlet.ErrorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
      <servlet-name>error</servlet-name>
      <url-pattern>/*</url-pattern>
    

6.5、ServletContext()

Quando o contêiner da web for iniciado, ele criará um objeto ServletContext correspondente para cada programa da web, que representa o aplicativo da web atual.

6.5.1. Dados compartilhados

Os dados salvos neste Servlet podem ser obtidos em outro Servlet

Insira a descrição da imagem aqui

Coloque dados ServletContext

public class HelloServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
//        this.getInitParameter()   初始化参数
//        this.getServletConfig()   Servlet配置
//        this.getServletContext()  Servlet上下文

        ServletContext context = this.getServletContext();
        String username = "hwt";//数据
        context.setAttribute("username",username);//将一个数据保存在了ServletContext中,名字为:username 值为:username
    }
}

Ler dados do ServletContext

public class GetServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}

Arquivo web.xml

<?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"
         metadata-complete="true">
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.hwt.servlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>getc</servlet-name>
    <servlet-class>com.hwt.servlet.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>getc</servlet-name>
    <url-pattern>/getc</url-pattern>
  </servlet-mapping>
</web-app>

Resultados de acesso de teste: O compartilhamento de dados de vários servlets pode ser alcançado por meio de ServletContext

6.5.2. Obtenha parâmetros de inicialização

web.xml

<!--  配置Web初始化参数-->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>
//获取参数
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}
6.5.3. Encaminhamento de solicitação

Insira a descrição da imagem aqui

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("进入了sd4");
        ServletContext context = this.getServletContext();
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
        requestDispatcher.forward(req,resp);//调用forward实现请求转发
    }
6.5.4. Encaminhamento de solicitação

Propriedades

  • Crie novas propriedades no diretório de arquivos Java
  • Crie novas propriedades no diretório de recursos

Eles são todos empacotados no mesmo caminho: classes, comumente conhecido como classpath.

Precisa usar um fluxo de arquivos

username=root
password=root
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

    InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

    Properties prop = new Properties();
    prop.load(is);
    String username = prop.getProperty("username");
    String pwd = prop.getProperty("password");
    resp.getWriter().print(username+":"+pwd);
}

6.6、HttpServletResponse

O servidor web recebe a solicitação http do cliente. Para esta solicitação, ele cria um objeto HttpServletRequest representando a solicitação e um HttpServletResponse representando a resposta.

  • Obtenha os parâmetros solicitados pelo cliente: use HttpServletResponse
  • Responder às informações do cliente: use HttpServletRequest
6.6.1. Classificação simples

Responsável pelo envio de dados para o navegador

ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;//中文

Responsável por enviar cabeçalhos de resposta ao navegador

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);

    void setDateHeader(String var1, long var2);
    void addDateHeader(String var1, long var2);
    void setHeader(String var1, String var2);
    void addHeader(String var1, String var2);
    void setIntHeader(String var1, int var2);
    void addIntHeader(String var1, int var2);

código de status de resposta

    int SC_CONTINUE = 100;
    int SC_SWITCHING_PROTOCOLS = 101;
    int SC_OK = 200;
    int SC_CREATED = 201;
    int SC_ACCEPTED = 202;
    int SC_NON_AUTHORITATIVE_INFORMATION = 203;
    int SC_NO_CONTENT = 204;
    int SC_RESET_CONTENT = 205;
    int SC_PARTIAL_CONTENT = 206;
    int SC_MULTIPLE_CHOICES = 300;
    int SC_MOVED_PERMANENTLY = 301;
    int SC_MOVED_TEMPORARILY = 302;
    int SC_FOUND = 302;
    int SC_SEE_OTHER = 303;
    int SC_NOT_MODIFIED = 304;
    int SC_USE_PROXY = 305;
    int SC_TEMPORARY_REDIRECT = 307;
    int SC_BAD_REQUEST = 400;
    int SC_UNAUTHORIZED = 401;
    int SC_PAYMENT_REQUIRED = 402;
    int SC_FORBIDDEN = 403;
    int SC_NOT_FOUND = 404;
    int SC_METHOD_NOT_ALLOWED = 405;
    int SC_NOT_ACCEPTABLE = 406;
    int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
    int SC_REQUEST_TIMEOUT = 408;
    int SC_CONFLICT = 409;
    int SC_GONE = 410;
    int SC_LENGTH_REQUIRED = 411;
    int SC_PRECONDITION_FAILED = 412;
    int SC_REQUEST_ENTITY_TOO_LARGE = 413;
    int SC_REQUEST_URI_TOO_LONG = 414;
    int SC_UNSUPPORTED_MEDIA_TYPE = 415;
    int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    int SC_EXPECTATION_FAILED = 417;
    int SC_INTERNAL_SERVER_ERROR = 500;
    int SC_NOT_IMPLEMENTED = 501;
    int SC_BAD_GATEWAY = 502;
    int SC_SERVICE_UNAVAILABLE = 503;
    int SC_GATEWAY_TIMEOUT = 504;
    int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
6.6.2. Aplicações comuns
  1. Mensagem de saída para o navegador

  2. ⇬ Fazer download do arquivo

    • Obtenha o caminho para o arquivo baixado
    • Obtenha o nome do arquivo baixado
    • Configure o navegador para suportar o download do que você precisa
    • Obtenha o fluxo de entrada do arquivo baixado
    • Criar buffer
    • Obtenha o objeto OutputStream
    • Grave o fluxo FileOutStream no buffer
    • Use OutPutStream para enviar dados no buffer para o cliente
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          
          
    //- 获取下载的文件名
            String realPath = "D:\\procedure2\\java\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\测试.jpg";
            System.out.println("下载路径为"+realPath);
    //  下载的文件名是啥?
            String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    //- 设置让浏览器支持下载需要的东西,中文文件名URLEncoder.encode编码,否则可能乱码
            resp.setHeader("Content-Disposition","attachment;fileName"+ URLEncoder.encode(fileName,"UTF-8"));
    //- 获取下载文件的输入流
            FileInputStream in = new FileInputStream(realPath);
    //- 创建缓冲区
            int len = 0;
            byte[] buffer = new byte[1024];
    //- 获取OutputStream对象
            ServletOutputStream out = resp.getOutputStream();
    //- 将FileOutStream流写入到buffer缓冲区,使用OutPutStream将缓冲区中的数据输出到客户端
            while ((len=in.read(buffer))>0){
          
          
                out.write(buffer,0,len);
            }
            in.close();
            out.close();
        }
    
    1. Implementação do código de verificação

      • Implementação front-end

      • A implementação de back-end requer o uso da classe picture do Java para produzir uma imagem

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  
                  
                //如何让浏览器3秒刷新一次
                resp.setHeader("refresh","3");
                //在内存中创建一个图片
                BufferedImage image = new BufferedImage(88, 20, BufferedImage.TYPE_INT_RGB);
                //得到图片
                Graphics2D g = (Graphics2D) image.getGraphics();
                //设置图片背景颜色
                g.setColor(Color.white);
                g.fillRect(0,0,80,20);
                //给图片写数据
                g.setColor(Color.BLACK);
                g.setFont(new Font(null,Font.BOLD,20));
                g.drawString(makeNum(),0,20);
                //告诉浏览器这个请求用图片打开
                resp.setContentType("image/jpeg");
                //网站存在缓存,不让浏览器缓存
                resp.setDateHeader("expires",-1);
                resp.setHeader("Cache-Control","no-cache");
                resp.setHeader("Pragma","no-cache");
                //把图片写给浏览器
                ImageIO.write(image,"jpg",resp.getOutputStream());
        
            }
            //生成随机数
            private String makeNum(){
                  
                  
                Random random = new Random();
                String num = random.nextInt(9999999) + "";
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < 7 - num.length(); i++) {
                  
                  
                    sb.append("0");
                }
                String s = sb.toString() + num;
                return s;
            }
        
      1. Implementar redirecionamento
        Insira a descrição da imagem aqui

        Depois que B receber a solicitação do cliente A, B notificará o cliente A para acessar outro recurso da web C. Este processo é o redirecionamento.

        Cenários comuns:

        • Login de usuário
        void sendRedirect(String var1) throws IOException;
        
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  
                  
                /*
                    resp.setHeader("Location","/r/img");
                    resp.setStatus(302);       
                */      
                resp.sendRedirect("/r/img");//重定向
            }
        

        A diferença entre redirecionar e capturar

        Mesmo ponto:

        • A página irá pular

        diferença:

        • Quando a solicitação for encaminhada, a URL não mudará 307
        • O URL mudará ao redirecionar 302
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              
              
              //处理请求
              String username = req.getParameter("username");
              String password = req.getParameter("password");
      
              System.out.println(username+"--"+password);
              //重定向时注意路径问题,路径错误报404
              resp.sendRedirect("/r/success.jsp");
          }
      
        <servlet>
          <servlet-name>RequestTest</servlet-name>
          <servlet-class>com.hwt.servlet.RequestTest</servlet-class>
        </servlet>
        <servlet-mapping>
          <servlet-name>RequestTest</servlet-name>
          <url-pattern>/login</url-pattern>
        </servlet-mapping>
      
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
          <h1>success</h1>
      </body>
      </html>
      

6.7、HttpServletRequest

HttpServletRequest representa a solicitação do cliente. O usuário acessa o servidor através do protocolo Http. Todas as informações da solicitação HTTP serão encapsuladas em HttpServletRequest. Todas as informações do cliente são obtidas através do método HttpServletRequest.

1. Obtenha os parâmetros passados ​​​​pelo front end e solicite o encaminhamento

req.getParameter()//获取一个
req.getParameterValues()//获取多个

Solicitar encaminhamento

public class LoginServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //后台接收中文乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");
        System.out.println("*******************************");
        //后台接收中文乱码问题
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println("*******************************");
        //通过请求转发
        //这里的/代表当前的web应用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}

7、Cookie、Sessão

7.1. Conversa

**Sessão:** o usuário abre um navegador, clica em vários links, acessa vários recursos da Web e fecha o navegador. Esse processo pode ser chamado de sessão.

Sessão com estado:

Como provar que você já fez login em um site antes?

servidor cliente

  1. O servidor envia uma carta ao cliente, e o cliente pode simplesmente trazer a carta consigo na próxima vez que visitar o servidor; cookie
  2. O servidor registra que você esteve aqui e irá combinar diretamente com você na próxima vez que você vier; seesion

7.2. Duas técnicas para salvar sessões

biscoito

  • Tecnologia do cliente (resposta, solicitação)

sessão

  • A tecnologia de servidor, usando esta tecnologia, pode salvar as informações da sessão do usuário. Você pode colocar informações ou dados na Sessão

Exemplo: Depois de fazer login no site, você não precisa fazer login novamente na próxima vez que usá-lo.

7.3、Biscoito

Insira a descrição da imagem aqui

  1. Obtenha informações de cookies a partir da solicitação

  2. O servidor responde ao cookie do cliente

    Cookie[] cookies = req.getCookies();//获得Cookie
    cookie.getName();//获得Cookie中的key
    cookie.getValue();//获得Cookie中的Value
    new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个Cookie
    cookie.setMaxAge(24*60*60);//设置Cookie有效时长
    resp.addCookie(cookie);//响应给客户端
    

    Cookie: Geralmente armazenado no diretório de usuário local appdata

    Existe um limite máximo para cookies em um site?

    • Um cookie só pode salvar uma informação;
    • Um site pode enviar vários cookies para o iBrowser e armazenar até 20 cookies;
    • O tamanho do cookie é limitado a 4kb;
    • Limite do navegador de 300 cookies.

    Apagar cookies

    • Se você não definir um limite de tempo, ele expirará automaticamente quando você fechar o navegador;
    • Defina o período de validade como 0;

codificar decodificar

URLEncoder.encode("测试","utf-8"))
URLDecoder.decode(cookie.getValue(),"utf-8")

7.4. Sessão (Pontos Chave)

Insira a descrição da imagem aqui

Sessão:

  • O servidor criará um objeto Session para cada usuário (navegador);
  • Uma Sessão ocupa um navegador.Enquanto o navegador não estiver fechado, esta Sessão existe;
  • Depois que o usuário fizer login, ele poderá acessar todo o site! —>Salvar informações do usuário;

A diferença entre Sessão e Cookie:

  • O cookie grava os dados do usuário no navegador do usuário e o navegador os salva (pode salvar vários)
  • A sessão grava os dados do usuário na sessão exclusiva do usuário e os salva no lado do servidor (salva informações importantes e reduz o desperdício de recursos do servidor)
  • O objeto de sessão é criado pelo serviço

usar:

  • Salve as informações do usuário logado;
  • Informações do carrinho de compras;
  • Os dados que são frequentemente utilizados em todo o site são geralmente armazenados em Sessão.

Sessão de uso:

public class SessionDome01 extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        //解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        //得到Session
        HttpSession session = req.getSession();

        //给Session中存东西
        session.setAttribute("name",new Person("测试",2));

        //获取Session的ID
        String sessionIdid = session.getId();

        //判断session是不是新创建的
        if (session.isNew()){
    
    
            resp.getWriter().write("session创建成功,ID"+sessionIdid);
        }else {
    
    
            resp.getWriter().write("session已经在服务器中存在了,ID"+sessionIdid);
        }
        //Session创建的时候做了什么事
//        Cookie cookie = new Cookie("JSESSIONID", sessionIdid);
//        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

    }
}

Obter sessão

public class SessionDome02 extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        //解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        //得到Session
        HttpSession session = req.getSession();

        Person person = (Person) session.getAttribute("name");
        System.out.println(person.toString());
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

    }
}

Sair da sessão

public class SessionDome03 extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        //解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8")
        //得到Session
        HttpSession session = req.getSession();
        session.invalidate();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

    }
}

Expiração automática da sessão: configuração web.xml

<!--    设置Session默认的失效时间-->
    <session-config>
<!--        15分钟后Session自动失效,以分钟为单位-->
        <session-timeout>15</session-timeout>
    </session-config>

Insira a descrição da imagem aqui

8. jsp

8.1. Definição

Páginas de servlet Java: páginas de servidor Java, usadas em tecnologia Web dinâmica como servlets!

A maior característica

  • Semelhante ao HTML
  • a diferença:
    • HTML fornece apenas dados estáticos aos usuários
    • As páginas JSP podem incorporar código Java para fornecer aos usuários dados dinâmicos

8.2. Princípios JSP

Processo de execução JSP:

  • O funcionamento interno do servidor

    Existe um diretório de trabalho no Tomcat;

    Usar o Tomcat no IDEA irá gerar um diretório de trabalho no Tomcat do IDE

    C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\65e27a1a-da4c-4252-87cb-54a11768bc5f\work\Catalina\localhost\javaweb_session_cookie_war\org\apache\jsp
    

Insira a descrição da imagem aqui

O arquivo jsp original se torna um arquivo Java

O navegador envia uma solicitação ao servidor e, independentemente do recurso acessado, ele está na verdade acessando o Servlet.

jsp eventualmente será convertido em classes Java

jsp é essencialmente um Servlet

//初始化
  public void _jspInit() {
    
    
  }
//销毁
  public void _jspDestroy() {
    
    
  }
//jspService
  public void _jspService(HttpServletRequest request, HttpServletResponse response) {
    
    
  1. Pedido de julgamento

  2. objetos embutidos

    final javax.servlet.jsp.PageContext pageContext;	//页面上下文
    javax.servlet.http.HttpSession session = null;		//session
    final javax.servlet.ServletContext application;		//application
    final javax.servlet.ServletConfig config;			//config
    javax.servlet.jsp.JspWriter out = null;				//out
    final java.lang.Object page = this;					//page:当前
    HttpServletRequest request;							//请求
    HttpServletResponse response;						//响应
    
  3. Código adicionado antes da saída da página

    response.setContentType("text/html");		//设置响应的页面类型
    pageContext = _jspxFactory.getPageContext(this, request, response,
         null, true, 8192, true);
    _jspx_page_context = pageContext;
    application = pageContext.getServletContext();
    config = pageContext.getServletConfig();
    session = pageContext.getSession();
    out = pageContext.getOut();
    _jspx_out = out;
    

    Os objetos acima podem ser usados ​​diretamente em páginas jsp
    Insira a descrição da imagem aqui

Na página JSP:

Contanto que seja um código JAVA, a saída será inalterada.

Se for código HTML, será substituído por:

 out.write("<h2>Hello World!</h2>\n");

Substitua o formato para o front-end!

8.3. Sintaxe básica JSP

Como uma aplicação da tecnologia Java, JSP possui algumas de suas próprias sintaxes estendidas, que são suportadas por todas as sintaxes em Java.

Expressão JSP

    <%--  JSP表达式
    作用:用来将程序的输出输出到客户端
    <%= 变量或者表达式 %>
    --%>
  <%= new java.util.Date() %>

Fragmento de script JSP

  <%
    int sum = 0;
    for (int i = 0; i <= 100; i++) {
      sum+=i;
    }
    out.println("<h1>Sum = "+sum+"</h1>");
  %>

Reimplementação de fragmentos de script

  <%
    int x = 10;
    out.println(x);
  %>
    <p>JSP文档</p>
  <%
    int y = 2;
    out.println(x);
    out.println(y);
  %>
  <hr>
<%--  在代码中嵌入HTML元素--%>
  <%
    for (int i = 0; i < 5; i++) {
  %>
    <h1>hello <%=i%></h1>
  <%
    }
  %>

Declaração JSP

<%!
  static {
    System.out.println("加载中");
  }
  private int a = 0;
  public void hwt(){
    System.out.println("hwt");
  }
%>

Declaração JSP: será compilada na classe Java gerada pelo JSP! Outros serão declarados no método jsp_Service!

Incorporar código Java em código JSP

<%%>
<%=%>
<%!%>
<%--注释--%>

Os comentários JSP não serão exibidos para o cliente, mas os comentários HTML serão exibidos para o cliente.

8.4. Instruções JSP

<%@page args... %>

Duas maneiras de mesclar páginas

    <%--@include会将两个页面合并
    	会导致变量冲突
    --%>
    <%@include file="common/header.jsp"%>
    <h1>主体</h1>
    <%@include file="common/footer.jsp"%>

    <hr>

    <%--
    jsp标签
    jsp:include:拼接页面,本质还是三个
    --%>
    <jsp:include page="common/header.jsp"/>
    <h1>网页主体</h1>
    <jsp:include page="common/footer.jsp"/>

8.5. Nove objetos integrados

  • PageContext armazena coisas
  • Solicitar para salvar algo
  • Resposta
  • Sessão salva coisas
  • Aplicação【ServletContext】salva coisas
  • Configurar【ServletConfig】
  • fora
  • página
  • Exceção
<%
pageContext.setAttribute("name1","测试一");//保存的数据只在一个页面中有效
request.setAttribute("name2","测试二");//保证村的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","测试三");//保证村的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","测试四");//保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%--
    脚本片段中的代码,会被原封不动生成到.jsp.java
    要求:这些代码必须保证java语法的正确性
--%>
<%
    //通过pagecontext取出,寻找的方式
    //从底层到高层(作用域):page->request->session->applocation
    //JSP:双亲委派机制:
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
%>
<%--使用el表达式取--%>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>

Solicitação: O cliente envia uma solicitação ao servidor, os dados gerados são inúteis após o usuário terminar de lê-los, como notícias.

Sessão: Uma solicitação enviada pelo cliente ao servidor. Os dados gerados podem ser utilizados pelo usuário após o uso, como um carrinho de compras.

Aplicação: O cliente envia uma solicitação ao servidor. Os dados gerados são utilizados por um usuário, mas outros usuários ainda podem utilizá-los, como registros de chat.

8.6, tags JSP, tags JSTL, expressões EL

 <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/taglibs/standard -->
<!--        standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

Expressão EL: ${}

  • recuperar dados
  • realizar operações
  • Obtenha objetos comuns usados ​​no desenvolvimento web

etiqueta jsp

<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="ceshi"/>
    <jsp:param name="password" value="root"/>
</jsp:forward>

Expressão JSTL

O uso da biblioteca de tags JSTL é para compensar as deficiências das tags HTML; ela personalizou muitas tags e as funções das tags são as mesmas dos códigos Java.

formatação de tags

Etiqueta SQL

Etiqueta XML

Tags principais (domínio)

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>//引入标签

Insira a descrição da imagem aqui

Etapas de uso da biblioteca de tags JSTL

  • Apresente o taglib correspondente
  • Use o método
  • O Tomcat também precisa introduzir o pacote jstl, caso contrário, um erro será relatado: erro de análise jstl

c: se

<body>
<h4>测试c:if</h4>
<form action="coreif.jsp" method="get">
    <%--
        el表达式获取表单中的数据
        ${param.参数名}
    --%>
    <input type="text" name="username" value="${param.username}"/>
    <input type="submit" value="登录">
</form>

<%--判断提交的是管理员,则登陆成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="管理员欢迎您"/>
</c:if>
<c:out value="${isAdmin}"/>

</body>

c: para cada

<%
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"张三");
    people.add(1,"李四");
    people.add(2,"王五");
    people.add(3,"赵六");
    request.setAttribute("list", people);
%>
<%--
var,    每一次遍历出来的变量
items, 要遍历的对象
begin,  哪里开始
end,    到哪里
step,  步长
--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"/><br>
</c:forEach>
<hr>

<c:forEach var="people" items="${list}" begin="1" end="3" step="2">
    <c:out value="${people}"/><br>
</c:forEach>

9. JavaBean

Classe de entidade

JavaBean tem uma maneira específica de escrever:

  • Deve haver um construtor sem parâmetros
  • As propriedades devem ser privadas
  • Deve haver métodos get/set correspondentes

Geralmente usado para mapear ORM para campos de banco de dados;

ORM: Mapeamento Relacional de Objeto

  • Tabela—>Classe
  • Campo ----> Atributo
  • Registro de linha ----> Objeto
eu ia nome idade endereço
1 Zhang San 3 Tianjin
2 John Doe 4 Pequim
3 Wang Wu 5 Nanquim
class People{
    
    
    private int id;
    private String name;
    private int age;
    private String address;
}
class A{
    
    
    new People(1,"张三",3"南京");
}
  • filtro
  • Upload de arquivo
  • Envio de e-mail
  • Revisão do JDBC: como usar o JDBC

10. Arquitetura MVC de três camadas

O que é MVC: Model View Controller modelo, visão, controlador

10.1. Primeiros dias:

Nos primeiros anos, os usuários tinham acesso direto à camada de controle. A camada de controle pode operar diretamente o banco de dados

servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护
servlet代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
    
   架构:没有什么是加一层解决不了的

10.2. Arquitetura de três camadas

Insira a descrição da imagem aqui

  • Modelo
    • Processamento de negócios: lógica de negócios (serviço)
      • CRUD de persistência de dados: (Dao)
  • Visualizar
    • mostrar dados
    • Forneça um link para iniciar uma solicitação de Servlet (
  • Controlador (servlet)
    • Receber solicitação do usuário (req: parâmetros de solicitação, informações da sessão...)
    • Entregue-o à empresa para lidar com o código
    • Salto de visualização de controle

Login—>Receber solicitação de login do usuário—>Processar solicitação do usuário (obter parâmetros de login do usuário, nome de usuário, senha) e entregá-la à camada de negócios para processar o negócio de login (determinar se a senha da conta está correta: transação)—>Camada Dao consulta se o nome de usuário e a senha estão corretos— >Banco de dados

11. Filtro (ponto chave)

Filtro: Filtro, usado para filtrar dados do site

  • Lidar com caracteres chineses ilegíveis
  • Autenticação de login

Insira a descrição da imagem aqui

Filtrar etapas de desenvolvimento

  1. Pacote de guia

    import javax.servlet.*;
    
  2. Implemente a interface Filter e reescreva o método correspondente

    public class CharacterEncodingFilter implements Filter {
          
          
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
          
          
            System.out.println("初始化");
        }
      @Override
      //filterChain:链
      /*
       *   1. 过滤所有代码,再过滤特定请求的时候都会执行
       *   2. 必须要让过滤器继续同行
       * filterChain.doFilter(servletRequest,servletResponse)
       * */
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
          
          
            servletRequest.setCharacterEncoding("utf-8");
            servletResponse.setCharacterEncoding("utf-8");
            servletResponse.setContentType("text/html;charset=UTF-8");
    
            System.out.println("CharacterEncodingFilter执行前");
            filterChain.doFilter(servletRequest,servletResponse);//如果不写,程序到这里会被拦截停止
            System.out.println("filterChain执行后");
        }
    
        @Override
        public void destroy() {
          
          
            System.out.println("销毁");
        }
    }
    
  3. Configurar filtro em web.xml

        <servlet>
            <servlet-name>ShowServlet</servlet-name>
            <servlet-class>com.hwt.ShowServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>ShowServlet</servlet-name>
            <url-pattern>/servlet/show</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>ShowServlet</servlet-name>
            <url-pattern>/show</url-pattern>
        </servlet-mapping>
    
        <filter>
            <filter-name>CharacterEncodingFilter</filter-name>
            <filter-class>com.hwt.filter.CharacterEncodingFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>CharacterEncodingFilter</filter-name>
            <url-pattern>/servlet/*</url-pattern>
        </filter-mapping>
    

12. Ouvinte

Implementar uma interface de ouvinte; N tipos de interfaces de ouvinte

  1. Escreva um ouvinte

    Implementar a interface do ouvinte

    //统计网站在线人数:统计session个数
    public class OnlineCountListener implements HttpSessionListener {
          
          
    
        @Override//创建session监听,一旦创建session就会触发事件
        public void sessionCreated(HttpSessionEvent se) {
          
          
            ServletContext ctx = se.getSession().getServletContext();
            Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
    
            if (onlineCount==null){
          
          
                onlineCount = new Integer(1);
            }else {
          
          
                int count = onlineCount.intValue();
                onlineCount = new Integer(count+1);
            }
            ctx.setAttribute("OnlineCount",onlineCount);
        }
    
        @Override//销毁session监听,一旦销毁session就会触发事件
        public void sessionDestroyed(HttpSessionEvent se) {
          
          
            ServletContext ctx = se.getSession().getServletContext();
            Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
    
            if (onlineCount==null){
          
          
                onlineCount = new Integer(0);
            }else {
          
          
                int count = onlineCount.intValue();
                onlineCount = new Integer(count-1);
            }
            ctx.setAttribute("OnlineCount",onlineCount);
        }
    }
    
  2. Registre o ouvinte em web.xml

    <!--    注册监听器-->
        <listener>
            <listener-class>com.hwt.listener.OnlineCountListener</listener-class>
        </listener>
    
  3. Se deve usá-lo depende da situação

13. Aplicações comuns de filtros e ouvintes

Listener, comumente usado em programação GUI

public class TestPanel {
    
    
    public static void main(String[] args) {
    
    
        Frame frame = new Frame("测试");//创建一个窗体
        Panel panel = new Panel(null);//面板
        frame.setLayout(null);//设置窗体布局

        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(0,0,255));//设置背景颜色
        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,255,0));//设置背景颜色
        frame.add(panel);
        frame.setVisible(true);

        //监听事件,监听关闭事件
        frame.addWindowListener(new WindowAdapter() {
    
    
            @Override
            public void windowClosing(WindowEvent e) {
    
    
                System.out.println("关闭ing");
            }
        });
    }
}

Somente após o login do usuário ele poderá entrar na página inicial! Após o usuário sair, ele não poderá entrar na página inicial.

  1. Depois que o usuário fizer login, coloque os dados do usuário na sessão

  2. Ao entrar na página inicial, é necessário determinar se o usuário está logado; utilizado em filtros

    public class SysFilter implements Filter {
          
          
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
          
          
        }
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain Chain) throws IOException, ServletException {
          
          
    
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
    
            if (request.getSession().getAttribute("USER_SESSION")==null){
          
          
                response.sendRedirect("/error.jsp");
            }
    
            Chain.doFilter(request,response);
        }
        @Override
        public void destroy() {
          
          
        }
    }
    

14. JDBC

JDBC: Java se conecta ao banco de dados, o que equivale a adicionar uma camada unificada de drivers entre vários bancos de dados.

Pacotes Jar que precisam ser importados

  • java.sql
  • javax.sql
  • driver de conexão mysql-connecter-java

base de dados

CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
);

INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'张三','123456','[email protected]','2000-01-01');

INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(2,'李四','123456','[email protected]','2000-01-01');

INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(3,'王五','123456','[email protected]','2000-01-01');

SELECT * FROM users

Importar dependências de banco de dados

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
    </dependencies>

Etapas fixas do JDBC

public class Testjdbc {
    
    
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
    
    
        //配置信息
        String url = "jdbc:mysql://localhost:3306/jdbc?userUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "root";
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.连接数据库
        Connection connection = DriverManager.getConnection(url, username, password);
        Statement statement = connection.createStatement();
        //4.编写sql
        String sql = "select * from users";
        //5.执行sql
        ResultSet rs = statement.executeQuery(sql);
        while (rs.next()){
    
    
            System.out.println("id"+rs.getObject("id"));
            System.out.println("name"+rs.getObject("name"));
            System.out.println("password"+rs.getObject("password"));
            System.out.println("email"+rs.getObject("email"));
            System.out.println("birthday"+rs.getObject("birthday"));
        }
        //6.关闭连接,释放资源
        rs.close();
        statement.close();
        connection.close();
    }
}

romances

Ou ambos têm sucesso ou ambos falham

Princípios ACID: atomicidade, consistência, isolamento, durabilidade

开启事务
    事务提交	commit()
    事务回滚	rollback()
关闭事务
    
转账
    A1000
    B1000
 经过转账后:两种情况 A900	B1100
    			  A1000  B1000
    

Operações de transação

public class Testjdbc2 {
    
    
    public static void main(String[] args) throws SQLException {
    
    
        //配置信息
        String url = "jdbc:mysql://localhost:3306/jdbc?userUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "root";
        Connection connection = null;
        //1.加载驱动
        try {
    
    
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.连接数据库
            connection = DriverManager.getConnection(url, username, password);
            //3.通知数据库开启事务,false 开启
            connection.setAutoCommit(false);

            String sql = "update account set money = money - 100 where name = 'A';";
            connection.prepareStatement(sql).executeUpdate();
            //错误
//            int i = 1 / 0;
            String sql2 = "update account set money = money + 100 where name = 'B';";
            connection.prepareStatement(sql2).executeUpdate();
            connection.commit();//两条都执行成功,才会提交事务
            System.out.println("success");
        } catch (Exception e) {
    
    
            try {
    
    
                connection.rollback();
                e.printStackTrace();
            } catch (SQLException ex) {
    
    
                ex.printStackTrace();
            }
        }finally {
    
    
            connection.close();
        }
    }
}

JavaWeb implementa upload de arquivo (organizado pelo Western Open Source Teacher Qinjiang)

1. Preparação

Para upload de arquivo, o navegador envia o arquivo ao servidor na forma de um fluxo durante o processo de upload.

Geralmente, o componente de upload de arquivo da ferramenta de código aberto common-fileupload do Apache é usado.

common-fileupload depende do pacote common-io, então você também precisa baixar este pacote.

Baixamos o pacote jar mais recente:

upload de arquivo comum: https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.4

common-io: https://mvnrepository.com/artifact/org.apache.commons/commons-io/1.3.2

Importe o pacote Jar no projeto JavaWeb:

Processo de upload de arquivo:

Insira a descrição da imagem aqui

2. Introdução às classes de uso

Notas sobre upload de arquivo

  1. Para garantir a segurança do servidor, os arquivos carregados devem ser colocados em um diretório inacessível ao mundo externo, como WEN-INF.
  2. Para evitar que arquivos com o mesmo nome sejam substituídos, especifique um nome de arquivo exclusivo para o arquivo.增加时间戳 -uuid -MD5 --位运算算法
  3. Limite o tamanho dos arquivos enviados.
  4. Você pode limitar o tipo de arquivos enviados. Ao receber um arquivo, determine se o sufixo do nome do arquivo é legal.

Explicação detalhada das aulas necessárias

ServletFileUpload é responsável por processar os dados do arquivo carregado e encapsular cada item de entrada no formulário em um objeto FileItem . O objeto DiskFileItemFactory é necessário ao usar o objeto ServletFileUpload para analisar a solicitação.

Portanto, precisamos construir o objeto DiskFileItemFactory antes de analisar e definir a propriedade fileItemFactory do objeto ServletFileUpload por meio do método de construção do objeto ServletFileItem ou setFileItemFactory() .

Classe FileItem

Deve haver um nome na página HTML:<p><input type="file" name="filename"></p>

<form action=""  method="post">
  <p><input type="file" name="file1"></p>
  <p><input type="file" name="file1"></p>
  <p><input type="submit"> | <input type="reset"></p>
</form>

Se o formulário contiver um item de upload de arquivo, o atributo entype do formulário deverá ser definido como multipart/form-data

/*
	通过表单上传文件
	get:上传文件大小有限制
	post:上传文件大小没有限制
*/
<form action="" enctype="multipart/form-data" method="post">
  上传用户:<input type="text" name="username"><br/>
  <p><input type="file" name="file1"></p>
  <p><input type="file" name="file1"></p>
  <p><input type="submit"> | <input type="reset"></p>
</form>

Se o tipo de formulário do navegador for multipart/form-data, o servidor deverá obter dados por meio do stream

[Introdução aos métodos comuns]

//isFormFile方法用于判断FileItem类对象封装的数据是一个普通文本表单//还是一个文件表单,如果时普通表单字段则返回true,否则返回false

booleanisField();//getFieldName方法用于返回表单标签name属性的值

String getFieldName();//getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回

String getString();//getName方法用于获得文件上传字段中的文件名。

String getName();//以流的形式返回上传文件的数据内容。

InputStream getInputStream();//delete方法用来清空FileItem类对象中存放的主体内容//如果主体内容被保存在临时文件中,delete方法将删除该临时文件

void delete();

ServletFileUpload类

ServletFileUpload é responsável por processar os dados do arquivo carregado e encapsular cada item de entrada no formulário em um objeto FileItem. Use seu método parseRequest(HttpServletRequest) para encapsular os dados enviados por meio de cada tag HTML no formulário em um objeto FileItem e, em seguida, retornado como um Lista. Este método é simples e fácil de usar para fazer upload de arquivos.

3. Escrita de código

package com.hwt.servlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileServlet extends HttpServlet {
    
    
    //private File file;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
    
    
        //判断上传的表单是普通表单还是带文件的表单,是返回true,否返回false;
        if (!ServletFileUpload.isMultipartContent(request)){
    
    
            return;//如果这是一个普通文件我们直接返回
        }//如果通过了这个if,说明我们的表单是带文件上传的
        //创建上传文件的保存目录,为了安全建议在WEB-INF目录下,用户无法访问
        String uploadpath = this.getServletContext().getRealPath("WEB-INF/Upload");//获取上传文件的保存路径
        File uploadfile = new File(uploadpath);
        if (!uploadfile.exists()){
    
    
            uploadfile.mkdir();//如果目录不存在就创建这样一个目录
        }
        /*//临时文件
        //临时路径,如果上传的文件超过预期的大小,我们将它存放到一个临时目录中,过几天自动删除,或者提醒用户转存为永久
        String tmppath = this.getServletContext().getRealPath("WEB-INF/tmp");
        File file = new File(tmppath);
        if (!file.exists()){
            file.mkdir();//如果目录不存在就创建这样临时目录
        }*/
        //处理上传的文件一般需要通过流来获取,我们可以通过request.getInputstream(),原生态文件上传流获取,十分麻烦
        //但是我们都建议使用Apache的文件上传组件来实现,common-fileupload,它需要依赖于common-io组件;
        try {
    
    
            //1、创建DiskFileItemFactory对象,处理文件上传路径或限制文件大小
            File file = null;
            DiskFileItemFactory factory = gteDiskFileItemFactory(file);
            //2、获取ServletFileUpload
            ServletFileUpload upload = getServletFileUpload(factory);
            //3、处理上传文件
            String msg = uploadParseRequest(upload,request,uploadpath);
            //Servlet请求转发消息
            request.setAttribute("msg",msg);
            request.getRequestDispatcher("/info.jsp").forward(request,response);
        }catch (FileUploadException e){
    
    
            e.printStackTrace();
        }
    }

    public static DiskFileItemFactory gteDiskFileItemFactory(File file){
    
    
        //1、创建DiskFileItemFactory对象,处理文件上传路径或限制文件大小
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //通过这个工厂设置一个缓冲区,当上传的文件大小大于缓冲区的时候,将它放到临时文件中;
        factory.setSizeThreshold(1024 * 1024);//缓冲区大小为1M
        factory.setRepository(file);
        return factory;
    }
    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) throws UnsupportedEncodingException {
    
    
        //2、获取ServletFileUpload
        ServletFileUpload upload = new ServletFileUpload(factory);
        //监听文件上传进度
        upload.setProgressListener(new ProgressListener() {
    
    
            @Override
            public void update(long pBytesRead, long lpContentLenght, int i) {
    
    
                //pBytesRead:已读取到的文件大小
                //pContentLenght:文件大小
                System.out.println("总大小:"+lpContentLenght+"已上传:"+pBytesRead);
            }
        });
        //处理乱码问题
        upload.setHeaderEncoding("UTF-8");
        //设置单个文件的最大值
        upload.setFileSizeMax(1024 * 1024 * 10);
        //设置总共能够上传文件的大小
        //1024 = 1kb * 1024 = 1M * 10 = 10M
        upload.setSizeMax(1024 * 1024 * 10);
        return upload;
    }
    public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest request,String uploadpath) throws IOException, FileUploadException {
    
    
        String msg = "";
        //3、处理上传文件
        //把前端的请求解析,封装成一个FileItem对象
        List<FileItem> fileItems = upload.parseRequest(request);
        for (FileItem fileItem : fileItems) {
    
    
            if (fileItem.isFormField()){
    
     //判断是普通表单还是带文件的表单
                //getFieldName指的是前端表单控件的name
                String name = fileItem.getFieldName();
                String value = fileItem.getString("UTF-8");//处理乱码
                System.out.println(name+":"+value);
            }else {
    
    //判断它是带文件的表单
                //======================处理文件=======================//
                //拿到文件的名字
                String uploadFileName = fileItem.getName();
                System.out.println("上传的文件名:"+uploadFileName);
                if (uploadFileName.trim().equals("") || uploadFileName == null){
    
    
                    continue;
                }
                //获得上传的文件名,例如/img/girl/ooa.jpg,只需要ooa,其前面的后面的都不需要
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                //获得文件的后缀名
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                /*
                 * 如果后缀名 fileExtName 不是我们需要的
                 *就直接return,不处理,告诉用户类型不对
                 * */
                System.out.println("文件信息【文件名:"+fileName+"文件类型:"+fileExtName+"】");
                //可以使用UUID(唯一通用识别码)来保证文件名的统一
                String uuidFileName = UUID.randomUUID().toString();
                //=======================传输文件=========================//
                //获得文件上传的流
                InputStream inputStream = fileItem.getInputStream();
                //创建一个文件输出流
                FileOutputStream fos = new FileOutputStream(uploadpath + "/" + uuidFileName +"."+ fileExtName);
                //创建一个缓冲区
                byte[] buffer = new byte[1024 * 1024];
                //判断是否读取完毕
                int len = 0;
                //如果大于0,说明还存在数据
                while ((len=inputStream.read(buffer))>0){
    
    
                    fos.write(buffer,0,len);
                }
                //关闭流
                fos.close();
                inputStream.close();
                msg = "文件上传成功!";
                fileItem.delete();//上传成功,清除临时文件
            }
        }
        return msg;
    }
}

loadException { String msg = ""; //3. Processar arquivos enviados // Analisar a solicitação de front-end e encapsulá-la em um objeto FileItem List fileItems = upload.parseRequest(request); for (FileItem fileItem : fileItems) { if ( fileItem.isFormField()){ //Determina se é um formulário normal ou um formulário com um arquivo //getFieldName refere-se ao nome do controle de formulário front-end String name = fileItem.getFieldName(); String value = fileItem. getString("UTF-8"); //Trata caracteres ilegíveis System.out.println(name+":"+value); }else {//Julga que é um formulário com um arquivo //











Processar arquivos=//
//Obter o nome do arquivo
String uploadFileName = fileItem.getName();
System.out.println("Nome do arquivo carregado: "+uploadFileName);
if (uploadFileName.trim().equals("") | | uploadFileName == null){ continue; } //Obtém o nome do arquivo enviado, como /img/girl/ooa.jpg, apenas oa é necessário, e os anteriores e seguintes não são obrigatórios String fileName = uploadFileName.substring( uploadFileName.lastIndexOf ("/") + 1); //Obtém o nome do sufixo do arquivo String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); /* * Se o nome do sufixo fileExtName não for o que precisamos * apenas retornar diretamente, não processado, informando ao usuário que o tipo está incorreto * */ System.out.println("Informações do arquivo [Nome do arquivo:"+fileName+"Tipo de arquivo:"+fileExtName+"]"); //UUID (código de identificação universal exclusivo) pode ser usado Para garantir a uniformidade dos nomes dos arquivos String uuidFileName = UUID.randomUUID().toString(); //=













Transferir arquivos===//
//Obter o fluxo de upload do arquivo
InputStream inputStream = fileItem.getInputStream();
//Cria um fluxo de saída do arquivo
FileOutputStream fos = new FileOutputStream(uploadpath + “/” + uuidFileName + “.” + fileExtName);
/ /Cria um buffer
byte[] buffer = new byte[1024 * 1024];
//Determina se a leitura foi concluída
int len ​​​​= 0;
//Se for maior que 0, significa que ainda há dados
while (( len=inputStream.read(buffer ))>0){ fos.write(buffer,0,len); } //Fecha o stream fos.close(); inputStream.close(); msg = "Arquivo enviado com sucesso!" ; fileItem.delete();/ /Upload bem-sucedido, limpe os arquivos temporários } } return msg; } }












Acho que você gosta

Origin blog.csdn.net/qq_44624801/article/details/129113638
Recomendado
Clasificación