Spring MVC [um artigo feito]

Primavera MVC

1. O que é Spring MVC

Descrição da documentação oficial:

O Spring Web MVC é a estrutura da Web original construída na API do Servlet e foi incluída na estrutura do Spring desde o início. Seu nome oficial "Spring Web MVC" vem do nome de seu módulo de origem (spring-webmvc), mas é frequentemente referido como "Spring MVC".

Resumo da descrição oficial:

1. Spring MVC é um framework web

2. O Spring MVC é construído com base na API do Servlet

Um dos frameworks que devem ser dominados na web no Spring.

2. Introdução ao MVC

MVC é a abreviação de Model View Controller. É um padrão de arquitetura de software na engenharia de software. É dividido em três partes básicas: Model (modelo), View (visualização) e Controller (controlador).

  • Modelo: é a parte da aplicação que é utilizada para processar a lógica dos dados da aplicação; geralmente o objeto modelo é responsável por acessar os dados no banco de dados.
  • View: A parte do aplicativo que lida com a exibição de dados; geralmente as visualizações são criadas a partir dos dados do modelo
  • Controlador: A parte do aplicativo que lida com a interação do usuário; (semelhante ao pessoal de segurança)

A figura a seguir é um fluxograma:

insira a descrição da imagem aqui

2.1, a relação entre Spring MVC e MVC

A relação entre os dois é semelhante à relação entre IoC e DI; MVC é uma ideia e Spring MVC é uma realização concreta da ideia MVC e é um produto de estrutura.

IoC descreve o objetivo e DI descreve as ideias específicas e alcançáveis.

Em geral: Spring MVC é uma estrutura da Web que implementa o padrão MVC e herda a API do Servlet.

Apesar de ser um framework web, quando o usuário insere a url, o projeto Spring MVC consegue perceber a requisição do usuário.

3. Criar Spring MVC

​ A criação do Spring MVC é baseada no Spring Boot, então os passos de criação anteriores são os mesmos do Spring Boot, até a figura a seguir, agora o link dependente é diferente

insira a descrição da imagem aqui

Aqui você precisa selecionar Spring Web in Web e então você pode ver Spring MVC na descrição interna.

Depois de clicar em próximo, você precisa esperar um pouco e, em seguida, excluir os arquivos redundantes no diretório após a ideia ser carregada; e algumas descrições de arquivos de diretório, você pode consultar o artigo criado pelo Spring Boot para o projeto.

insira a descrição da imagem aqui

Quarto, domine o núcleo do Spring MVC☆☆☆☆

Aprender Spring MVC só precisa dominar 3 funções:

1. A função de conexão: conectar o usuário (browser) com o programa java, simplesmente falando, acessando um endereço url pode chamar nosso programa Spring.

2. A função de obtenção de parâmetros: o usuário trará alguns parâmetros ao acessar, e encontrará uma forma de obter os parâmetros no programa.

3. A função de saída de dados: Depois de executar a lógica de negócios, o resultado da execução precisa ser devolvido ao usuário.

Essas três funções são o núcleo do Spring MVC, ou seja, dominar essas três funções também dominará o Spirng MVC. A seguir, a análise detalhada e o uso dessas três funções.

4.1. Implantação do Spring Hot

​ Aqui está também a configuração da implantação a quente do Spring. A implantação a quente significa que a ideia atualizará e implantará automaticamente o código mais recente. Não permitirá que você reinicie o programa Spring MVC toda vez que codificar, caso contrário, será muito problemático. Use implantação a quente para atualizar automaticamente Implante o código e você pode acessar a url sem reiniciar o programa novamente.

No entanto, pode não ser bem-sucedido ao carregar uma nova turma. Aguarde cerca de 5 segundos. Se não for bem-sucedido, você pode reiniciá-lo. O efeito da implantação a quente pode não ser muito bom para alterações de arquivo, mas não há problema para modificar o código

1. Primeiro, adicione dependências, suporte à estrutura de ferramenta de desenvolvimento

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
</dependency>

2. Ative a compilação automática do projeto atual no idea

insira a descrição da imagem aqui

3. Ative a implantação ativa do tempo de execução

insira a descrição da imagem aqui

A versão da minha ideia é relativamente antiga. Se a versão da sua ideia atual for relativamente alta ou se você não encontrar a opção ...app.runinng, poderá executar as seguintes operações:

insira a descrição da imagem aqui

Por fim, use debug para iniciar o projeto em vez do método run (caso contrário, será inválido)

4.2. Realize a conexão entre usuários e programas☆

Os códigos a seguir foram usados ​​no Spring Boot e são relativamente fáceis de entender.

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping("/user") // 路由地址
public class UserController {
    
    
    
    @RequestMapping("/hi") //localhost:8080/user/hi
    public String hi() {
    
    
        return "Hello ,Spring MVC!!!";
    }
}

Inicie o programa Spring MVC e digite o endereço url para acessar a página do navegador.

4.2.1、@RequestMapping

A principal coisa a se prestar atenção neste código é @RequestMappinga anotação, que pode modificar tanto a classe quanto o método.Por padrão, ela suporta tanto requisições GET quanto requisições post.

imagem-20230809114111963

Mas @RequestMappingas anotações também podem definir o tipo de solicitação;

@RequestMapping(value = "/user" , method = RequestMethod.POST) // 路由地址

O valor do parâmetro é o valor padrão, que pode ser omitido somente durante o roteamento. O parâmetro do método é usado para definir o tipo de solicitação. Você pode abri-lo na ideia para visualizar o código-fonte para oferecer suporte a esses parâmetros de solicitação.

Neste momento, a solicitação Post é definida. Quando a solicitação Get é usada, um prompt de erro 401 Method Not Allowed será relatado.

4.2.2、@GetMapping/@PostMapping

Essas duas anotações são, na verdade, iguais ao método de configuração de parâmetros na anotação @RequestMapping, dependendo de qual método você está acostumado.

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping("/user") // 路由地址
public class UserController {
    
    
    
    @PostMapping("/hi2") // http://localhost:8080/user/hi2
    public String hi2() {
    
    
        return "Hello ,Spring MVC2!!!";
    }
}

Ou seja, este código suporta apenas solicitações Post e, se você usar solicitações Get forçosamente, ele solicitará 405. O uso de @GetMapping também é o mesmo motivo, portanto, não o repetirei aqui.

4.3. Obter parâmetros☆

4.3.1, passar um único parâmetro

​ Os parâmetros formais no código devem ser consistentes com os parâmetros formais passados ​​pelo front-end

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping(value = "/user" ) // 路由地址  method = RequestMethod.POST
public class UserController {
    
    

    @RequestMapping("/hi4") //localhost:8080/user/hi4
    public String hi4(String name) {
    
    
        return "Hello "+name;
    }
}

URL:

http://localhost:8080/user/hi4?name=python

O código deve ser consistente com o nome do parâmetro passado pelo front end, e o resultado final da impressão é python; se nada for digitado, um nulo é retornado.

4.3.2, objeto de transferência

Primeiro, deve haver um objeto:

import lombok.Data;
@Data // 复合注解,基于lombok依赖,里面包含了 @Getter + @Setter + @ToString
public class User {
    
    
    private int id;
    private String name;
    private String password;
    private int age;
}

pegue o objeto:

@Controller
@ResponseBody // 返回一个非静态页面的数据
@RequestMapping(value = "/user" ) // 路由地址  method = RequestMethod.POST
public class UserController {
    
    
    @RequestMapping("/add") // localhost:8080/user/add
    public String add(User user) {
    
     // 这里就是拿到了这个对象
        return user.toString();
    }
}

URL:

http://localhost:8080/user/add?id=1&name=java&password=123&age=18

resultado:

User(id=1, name=java, password=123, age=18)

Se o nome do parâmetro no URL não corresponder ao nome do parâmetro no código de back-end, o atributo não correspondente no objeto será nulo

4.3.3. Parâmetros de passagem de formulário

Isso pode ser entregue principalmente pelo carteiro, basta inseri-lo diretamente

imagem-20230809150331689

4.3.4, parâmetros de front-end de mapeamento de back-end

​ Afinal, front-end e back-end são separados, então o código não é escrito pela mesma pessoa. Às vezes, quando o trabalho é entregue, o novato muda o nome do parâmetro do velho. Se o front-end estiver inconsistente, o parâmetros de front-end não podem ser recebidos.Há duas maneiras de resolver este problema.

1. Alterar a senha do back-end para pwd. Este método não é aceitável. Quando o projeto é grande, alterar o nome implicará em outros códigos do back-end. Quanto mais você alterar, mais erros cometerá, portanto, este método não é aconselhável❌ ❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌❌

2. Use @RequestParamanotações para mapear valores de parâmetros front-end e back-end

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/login") //localhost:8080/user/login
    public String login(String name ,@RequestParam("pwd") String password) {
    
    
        return "name= " + name+ "| password=" +password;
    }
}

Mapeie o parâmetro pwd do front-end para a variável de senha do back-end

URL:

http://localhost:8080/user/login?name=java&pwd=987

Resultado: nome=java|senha=987

Com @RequestParama anotação, mesmo que o front-end passe o pwd, os parâmetros do back-end também podem ser bem mapeados para o front-end.

4.3.5, @RequestParam (o parâmetro não é nulo)

Como pode ser visto acima, a primeira função pode ser renomeada para realizar o mapeamento front-end e back-end; a segunda função é que o parâmetro não pode ser nulo; exemplo: ao realizar uma operação de login, a conta e a senha devem ser inserido. Para evitar que seja nulo, você pode defini-lo nesse parâmetro Anotar na frente @RequestParam;

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    
    @RequestMapping("/login2") //localhost:8080/user/login2
    public String login2(@RequestParam String name ,@RequestParam String password) {
    
    
        return "name= " + name+ "| password=" +password;
    }
}

url:

localhost:8080/user/login2?name=java

Erro:

{

“timestamp”: “2023-08-09T07:28:59.552+00:00”,

“estado”: ​​400,

“erro”: “Solicitação inválida”,

}

O prompt é que a solicitação falhou, portanto, após adicionar a anotação @RequestParam, seus parâmetros não podem ser nulos

4.3.6, parâmetros opcionais

@RequestParamA terceira função é que depois de definir o mapeamento dos parâmetros de front-end e back-end, é um parâmetro opcional. Há um pedaço de código no código-fonte da anotação @RequestParaméboolean required() padrão true;O significado deste código é que ele deve ser passado, se você mudar seu parâmetro para false, não é necessário passar.

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/login3") //localhost:8080/user/login2
    public String login3(@RequestParam String name ,@RequestParam(value = "pwd",required = false) String password) {
    
    
        return "name= " + name+ "| password=" +password;
    }
}

URL:

localhost:8080/user/login3?name=java

resultado:

nome= java| senha=nulo

Os programadores definem required = false para defini-lo como um parâmetro não obrigatório.


@RequestParamResumo da função:

1. Mapeamento de parâmetros front-end e back-end;

2. Defina os parâmetros necessários;

3. Mapeamento de parâmetros de front-end e back-end + parâmetro opcional necessário = false


4.3.7. Obter um objeto Json

A obtenção do objeto Json do front-end requer uma anotação, @RequestBodyessa anotação permite que o back-end saiba que os dados passados ​​pelo front-end são um formato Json.

Se não estiver anotado, o back-end responderá com um nulo se não puder receber

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/loginByJson") // localhost:8080/user/loginByJson
    public String loginByJson(@RequestBody User user){
    
     // Json 是对象要用对象来接受形参
        return "name= " + user.getName()+ "| password=" +user.getPassword();
    }
}

Json:

{
    
    "name":"java","password":"123"}

resultado:

nome= java| senha=123

Anotações devem ser adicionadas para obter os dados no formato Json do front end @RequestBody. Ela disse que o backend deve ser solicitado a obter dados no formato Json do front end.

4.3.8. Obtenha os parâmetros na URL

O endereço url em circunstâncias normais: http://localhost:8080/login ?name…

Mas alguns endereços url: http://localhost:8080/ {name}/{password}…

Algumas empresas usam palavras-chave para ter uma classificação de pesquisa mais alta nos mecanismos de pesquisa. O endereço geral da url é seguido por parâmetros, mas algumas urls: http://localhost:8080/java/ Como aprender bem o java ? URLs como /123/… terão palavras-chave e terão uma classificação mais alta nos mecanismos de pesquisa.

​ Em seguida, obtenha os parâmetros do caminho do URL necessário para usar @PathVariableanotações, implementação de código:

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    
    @RequestMapping("/loginByPath/{name}/{passwrod}") 
    public String loginByPath( @PathVariable String name,
                               @PathVariable("passwrod") String pwd) {
    
    
        return "name= " + name+ "| password=" +pwd;
    }
}

URL:

http://localhost:8080/user/loginByPath/java/234

resultado:

nome= java| senha=234


Resumo @PathVariabletem duas funções:

1. Obtenha os parâmetros no URL

2. @RequestParamTem a função de mapeamento de front-end e back-end com anotações, correspondendo a {password} na url do front-end


4.3.9. Obter arquivos enviados

Quando o front-end passa uma imagem ou um arquivo, uma das anotações no Spring @RequestParté receber o arquivo e, em seguida, colocar o arquivo no diretório especificado.

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/upFile") // localhost:8080/user/upFile
    public String upFile(Integer id, @RequestPart("photo")MultipartFile file) throws IOException {
    
    
        //业务处理....
        file.transferTo(new File("E:\\a.png"));
        return "id:"+id+" 图片上传成功!";
    }
}

A "foto" na anotação @RequestPartcorresponde aos parâmetros do front-end. Aqui, o carteiro é usado para simular o front-end

imagem-20230810095128576

Mas há um problema com este código. Quando você precisa transferir imagens em lotes, transferi-las para a unidade E irá sobrescrever diretamente um.png e nenhum novo arquivo será gerado. Portanto, o código precisa ser melhorado para permitir que cada arquivo para gerar um id único, para que não seja engolido pela cobertura.

@Controller
@ResponseBody 
@RequestMapping(value = "/user" ) 
public class UserController {
    
    

    @RequestMapping("/upFile") // localhost:8080/user/upFile
    public String upFile(Integer id, @RequestPart("photo")MultipartFile file) throws IOException {
    
    
        //业务处理....
        // 1、生成唯一的id
        String fileName = UUID.randomUUID().toString(); // UUID是唯一id:时间轴+网卡号+随机数....
        // 2、获取上传文件名的后缀
        String fileType = file.getOriginalFilename().substring(
                file.getOriginalFilename().lastIndexOf(".") 
        ); // 获取后缀名
        fileName += fileType; // 组成完整的文件名
        file.transferTo(new File("E:\\"+fileName));
        return "id:"+id+" 图片上传成功!";
    }

imagem-20230810100350375

Use o UUID no programa java para gerar um id exclusivo e, em seguida, interceptar o sufixo do arquivo e adicionar o id e o sufixo exclusivos para formar uma nova imagem completa e passá-la para o diretório especificado; mas o diretório especificado é melhor configurado em a configuração O resumo do arquivo é conveniente para a manutenção final, se você não entender o código, basta alterar o arquivo de configuração.

4.3.10. Obter Cookie/Sessão/cabeçalho

Por que existem Cookies e Sessões? Porque no protocolo http ou no protocolo https, suas características são sem conexão (sem conexão longa, apenas uma resposta), sem estado (a última solicitação enviada não tem nada a ver com a anterior), por exemplo, o login em um site requer insira a senha da conta, devido às características do protocolo http, você digitará o número da conta e a senha toda vez que visitar as informações neste site, o que é muito problemático e tem uma experiência de usuário muito ruim. Para resolver este problema , cookies e sessões aparecem;

Cookie: quando um usuário faz login pela primeira vez em um site com um número de conta e senha, o navegador armazena as informações de login bem-sucedidas no cookie para que, ao visitar outras páginas do site, suas informações sejam verificadas e não haja necessidade de faça login novamente; mas cookies Uma desvantagem é que as informações do cookie são armazenadas no lado do atendimento ao cliente. Se houver um lado do cliente, problemas de segurança serão considerados. Os usuários podem simular cookies e escrever algumas de suas próprias coisas nos cookies. Em a fim de resolver problemas de segurança, as sessões aparecem.

Sessão: Para resolver o problema causado pelo Cookie, a Sessão coloca as informações do usuário no servidor, e a Sessão também é um par chave-valor armazenado no servidor, e o valor id da Sessão é alterado dinamicamente. o Cookie, o navegador encontrará o valor correspondente no servidor após obter o id da sessão, resolvendo assim o problema, mas a sessão não é absolutamente segura, porque algumas pessoas sequestram o id da sessão e usam o id para encontrá-lo no servidor ., mas uma característica do Session é que o id é alterado dinamicamente. Quando você obtém o id, o id pode ter mudado. Relativamente falando, a segurança é relativamente alta, mas não é absolutamente segura.

4.3.11. Obtenção de Cookies

O método de anotação Spring MVC é usado aqui, @CookieValuemas o método Sevelet também pode ser usado.

@Controller
@ResponseBody 
@RequestMapping(value = "/user") 
public class UserController {
    
    

    @RequestMapping("/getCookie") // localhost:8080/user/getCookie
    public String getCookie(@CookieValue String name) {
    
    
        return "Cookie-name=" + name;
    }
}

@CookieValue(“xxx”), o parâmetro name do Cookie está entre colchetes, o que é consistente com o parâmetro name, portanto não há necessidade de adicionar colchetes

Por ser uma simulação, então configure a simulação no navegador

imagem-20230810121629577

4.3.12. Obtenha o cabeçalho

​ User-Agent é um cabeçalho comum em requisições.

@Controller
@ResponseBody 
@RequestMapping(value = "/user") 
public class UserController {
    
    

    @RequestMapping("/getAgent") // localhost:8080/user/getAgent
    public String getAgent(@RequestHeader("User-Agent") String userAgent) {
    
    
        return userAgent;
    }
}

Obtenha a anotação utilizada pelo User-Agent no protocolo http @Requestheader.

4.3.13. Obter Sessão

Por se tratar de uma simulação, primeiro defina e armazene uma sessão por conta própria.

@Controller
@ResponseBody 
@RequestMapping(value = "/user") 
public class UserController {
    
    
    @RequestMapping("/setSession") // localhost:8080/user/setSession
    public String setSession(String name, HttpServletRequest req) {
    
    
        HttpSession session = req.getSession(true); // 有Session就获取,没有就创建
        if (session != null) {
    
    
            session.setAttribute("name", name);
        }
        return "Session 设置成功!";
    }
}

URL:

localhost:8080/user/setSession?name=java

Obter sessão:

@Controller
@ResponseBody 
@RequestMapping(value = "/user")
public class UserController {
    
    
    @RequestMapping("/getSession") 
    public String getSession(@SessionAttribute(name = "name", required = false) String name) {
    
    
        return name;
    }
}

URL:

// localhost:8080/user/getSession

4.4. Dados de entrada

Dados de retorno Por padrão, uma página estática é retornada. Para a saída da página estática, escreva o código da página estática no diretório e, em seguida, ative o acesso à url no back-end.

@Controller
public class TestController {
    
    

    @RequestMapping("/index") // localhost:8080/index
    public String getIndex() {
    
    
        return "index.html";
    }
}

​ O código acima não adiciona @ResponseBody, então a saída é sempre uma página estática, e agora uma função de calculadora é concluída para que retorne um dado.

@Controller
public class TestController {
    
    

    @RequestMapping("/calc") //localhost:8080/calc
    @ResponseBody
    public String calc(Integer num1, Integer num2) {
    
    
        return "计算结果:" + (num1 + num2);
    }
}

URL:

http://localhost:8080/calc?num1=5&num2=10

resultado:

Resultado calculado: 15

Esta é a página retornada usando @ResponseBody is data, e foi mencionado várias vezes que @ResponseBody não será rastreado adicionalmente.

4.4.1. Retorno do objeto Json

​ Retornar um objeto Json requer um HashMap para retornar o formato do objeto Json:

@Controller
public class TestController {
    
    

    @RequestMapping("/json") // localhost:8080/json
    @ResponseBody
    public HashMap<String,String> json() {
    
    
        HashMap<String ,String > hashMap = new HashMap<>();
        hashMap.put("name","java");
        hashMap.put("password","123");
        return hashMap;
    }
}

​ Caso não use o método HashMap, você usa o método de impressão de string, que não faz diferença para o usuário na página do navegador, mas para a transmissão do front-end é o tipo de formato html, quando o front-end usa data, ele não irá reconhecê-lo. Para, mais erros podem ocorrer, então ao usar dados Json, o back-end precisa usar HashMap.

4.5. Encaminhamento e redirecionamento

encaminhar VS redirecionar

  • redirecionar (redirecionar): a URL se torna uma URL redirecionada, a exibição da página é normal e os links externos podem ser acessados;
  • Forward (reencaminhamento): A URL não foi alterada, pode haver problemas com as páginas acessadas e recursos externos podem não ser carregados (o reencaminhamento é feito pelo lado do servidor, podendo haver problemas no posicionamento do endereço de roteamento)
@Controller
//@ResponseBody
@RequestMapping("/test")
public class TestController {
    
    

    @RequestMapping("/myForward") // localhost:8080/test/myForward
    public String myForward() {
    
    
        return "forward:/test.html";
    }

    @RequestMapping("/myRedirect") // localhost:8080/test/myRedirect
    public String myRedirect() {
    
    
        return "redirect:/test.html";
    }
}

​ Em um caso, é mais conveniente usar o redirecionamento, mas é problemático e sujeito a erros de encaminhamento, mas lembre-se da diferença entre os dois, que geralmente é testada em entrevistas.

Acho que você gosta

Origin blog.csdn.net/qq_54219272/article/details/132240238
Recomendado
Clasificación