Guia rápido para controladores de mola
1. Introdução
Neste artigo, vamos nos concentrar em um conceito central em Spring MVC - Controladores.
2. Visão geral
Vamos começar dando um passo para trás e dando uma olhada emthe concept of the Front Controller in the typical Spring Model View Controller architecture.
Em um nível muito alto, aqui estão as principais responsabilidades que estamos considerando:
-
Intercepta solicitações recebidas
-
Converte a carga útil da solicitação na estrutura interna dos dados
-
Envia os dados paraModel para processamento posterior
-
Obtém dados processados deModele avança esses dados paraView para renderização
Aqui está um diagrama rápido para o fluxo de alto nível emSpring MVC:
Como você pode ver,DispatcherServlet desempenha o papel deFront Controller na arquitetura.
O diagrama é aplicável tanto aos controladores MVC típicos quanto aos controladores RESTful - com algumas pequenas diferenças (descritas abaixo).
Na abordagem tradicional, os aplicativosMVC não são orientados a serviços, portanto, há um View Resolver que renderiza visualizações finais com base nos dados recebidos de aController.
Os aplicativosRESTful são projetados para serem orientados a serviços e retornar dados brutos (JSON / XML normalmente). Como esses aplicativos não fazem nenhuma renderização de visualização, não háView Resolvers - geralmente se espera que oController envie dados diretamente por meio da resposta HTTP.
Vamos começar com os controladores estilo MVC0.
3. Dependências do Maven
Para poder trabalhar comSpring MVC, vamos primeiro lidar com as dependências do Maven:
org.springframework
spring-webmvc
5.0.6.RELEASE
Para obter a versão mais recente da biblioteca, dê uma olhada emspring-webmvc on Maven Central.
4. Project Web Config
Agora, antes de olhar para os próprios controladores, primeiro precisamos definir um projeto web simples e fazer uma configuração rápida deServlet.
Vamos primeiro ver comoDispatcherServlet pode ser configurado sem usarweb.xml - mas em vez de usar um inicializador:
public class StudentControllerConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext root =
new AnnotationConfigWebApplicationContext();
root.register(WebConfig.class);
root.refresh();
root.setServletContext(sc);
sc.addListener(new ContextLoaderListener(root));
DispatcherServlet dv =
new DispatcherServlet(new GenericWebApplicationContext());
ServletRegistration.Dynamic appServlet = sc.addServlet("test-mvc", dv);
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/test/*");
}
}
Para configurar as coisas sem XML, certifique-se de terservlet-api 3.1.0 em seu classpath.
Aqui está como oweb.xml ficaria:
test-mvc
org.springframework.web.servlet.DispatcherServlet
1
contextConfigLocation
/WEB-INF/test-mvc.xml
Estamos definindo a propriedadecontextConfigLocation aqui - apontando para o arquivoXML usado para carregar o contexto Spring. Se a propriedade não estiver lá, o Spring irá procurar por um arquivo chamado{servlet_name}-servlet.xml.
No nosso caso,servlet_name étest-mvce, neste exemplo, oDispatcherServlet procuraria por um arquivo chamadotest-mvc-servlet.xml.
Finalmente, vamos definir oDispatcherServlet e mapeá-lo para umURL particular - para terminar nosso sistema baseado emFront Controller aqui:
test-mvc
/test/*
Assim, neste caso, oDispatcherServlet interceptaria todas as solicitações dentro do padrão/test/*.
5. Spring MVC Web Config
Vamos agora ver comoDispatcher Servlet pode ser configurado usandoSpring Config:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {
"org.example.controller.controller",
"org.example.controller.config" })
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean =
new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/");
bean.setSuffix(".jsp");
return bean;
}
}
Vamos agora dar uma olhada na configuração deDispatcher Servlet usandoXML. Um instantâneo do arquivoDispatcherServlet XML - o arquivoXML queDispatcherServlet usa para carregarcontrollerse outrosSpringentities personalizados é mostrado abaixo:
/WEB-INF/
.jsp
Com base nessa configuração simples, é claro que a estrutura inicializará qualquer bean de controlador que encontrar no caminho de classe.
Observe que também estamos definindo o View Resolver, responsável pela renderização da visualização - usaremosInternalResourceViewResolver do Spring aqui. Isso espera que um nome deview seja resolvido, o que significa encontrar uma página correspondente usando prefixo e sufixo (ambos definidos na configuraçãoXML).
Então, por exemplo, seController retorna umview chamado “welcome”*,* oviewresolver vai tentar resolver uma página chamada“welcome.jsp” emWEB-INF pasta.
6. O controlador MVC
Não vamos finalmente implementar o controlador de estilo MVC.
Observe como estamos retornando um objetoModelAndView - que contém ummodel mape umview object; ambos serão usados pelo View Resolver para renderização de dados:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@GetMapping
public ModelAndView getTestData() {
ModelAndView mv = new ModelAndView();
mv.setViewName("welcome");
mv.getModel().put("data", "Welcome home man");
return mv;
}
}
Então, o que exatamente montamos aqui.
Primeiro, criamos um controlador chamadoTestControllere o mapeamos para o caminho“/test”. Na classe, criamos um método que retorna um objetoModelAndView e é mapeado para uma solicitaçãoGET, portanto, qualquer chamada de URL terminando com “test” seria roteada porDispatcherServlet para o métodogetTestData emTestController.
E, claro, estamos retornando o objetoModelAndView com alguns dados do modelo para uma boa medida.
O objeto de visualização tem um nome definido como “welcome“. Conforme discutido acima, oView Resolver irá procurar uma página na pastaWEB-INF chamada “welcome.jsp“.
Abaixo você pode ver o resultado de uma operaçãoGET de exemplo:
Observe queURL termina com“test”. O padrão deURL é“/test/test “.
O primeiro“/test” vem do Servlet, e o segundo vem do mapeamento do controlador.
7. Mais dependências de Spring para REST
Vamos agora começar a olhar para um controlador RESTful. Obviamente, um bom lugar para começar são as dependências extras do Maven que precisamos para isso:
org.springframework
spring-webmvc
5.0.6.RELEASE
org.springframework
spring-web
5.0.6.RELEASE
com.fasterxml.jackson.core
jackson-databind
2.9.5
Por favor, consulte os linksjackson-core,spring-webmvcespring-web para as versões mais recentes dessas dependências.
Jackson obviamente não é obrigatório aqui, mas certamente é uma boa maneira de habilitar o suporte JSON. Se você estiver interessado em mergulhar mais fundo nesse suporte, dê uma olhada emmessage converters article here.
8. O controlador REST
A configuração de um aplicativoSpring RESTful é a mesma que a do aplicativoMVC, com a única diferença sendo que não há View Resolversemodel map.
A API geralmente simplesmente retornará dados brutos ao cliente - representaçõesXMLeJSON normalmente - e entãoDispatcherServlet ignoraview resolversereturns the data right in the HTTP response body.
Vamos dar uma olhada em uma implementação de controlador RESTful simples:
@Controller
public class RestController {
@GetMapping(value = "/student/{studentId}")
public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
Student student = new Student();
student.setName("Peter");
student.setId(studentId);
return student;
}
}
Observe a anotação@ResponseBody no método - que instrui o Spring a ignorarview resolvereessentially write out the output directly to the body of the HTTP response.
Um instantâneo rápido da saída é exibido abaixo:
A saída acima é o resultado do envio da solicitaçãoGET para a API com o alunoid de1.
Uma observação rápida aqui é -the @RequestMapping annotation é uma daquelas anotações centrais que você realmente terá que explorar para usar todo o seu potencial.
9. Spring Boot e a anotação@RestController
A anotação@RestController do Spring Boot é basicamente um atalho rápido que nos poupa de sempre ter que definir@ResponseBody.
Aqui está o controlador de exemplo anterior usando esta nova anotação:
@RestController
public class RestAnnotatedController {
@GetMapping(value = "/annotated/student/{studentId}")
public Student getData(@PathVariable Integer studentId) {
Student student = new Student();
student.setName("Peter");
student.setId(studentId);
return student;
}
}
10. Conclusão
Neste guia, exploramos os conceitos básicos do uso de controladores no Spring, tanto do ponto de vista de um aplicativo MVC típico quanto de uma API RESTful.
É claro que todo o código do artigo está disponívelover on GitHub.