Spring MVC

Co je MVC?

  • návrhový vzor - odděluje data z aplikační domény od prezentační vrsty a od událostí
  • Model - udržuje a upravuje data
  • View - zobrazuje data z modelu
  • Controller - zpracovává uživatelský vstup, upravuje model a odesílá ho do view

Konfigurace

  • buď web.xml 
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
  xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

Konfigurace

  • nebo třídou - ve Springu implementace WebApplicationInitializer
public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        WebApplicationContext context = getContext();
        servletContext.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
            "DispatcherServlet", new DispatcherServlet(context));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

Model

  • klasická POJO
  • atributy které chceme použít ve view musí mít getter
public class Student {

    private int Id;
    private String name;

    //get & set
}

Controller

  • třída anotovaná @Controller
  • metody anotované @RequestMapping
@RequestMapping("/hello")
public String request(Model model) {

    model.addAttribute("test", "testVal");
    return "hello";
}

Controller

  • @RequestMapping specifikuje:
    • URL adresu kterou metoda obsluhuje
    • Typ metody
    • Příchozoj formát dat
    • Odchozí formát dat
    • Povinné parametry
    • Povinné elementy hlavičky
 @RequestMapping(value = "/hello", method = RequestMethod.GET,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_XML_VALUE,
            headers="Content-Type=application/json",
            params = "id")

View

  • Zodpovědné za zobrazení dat uživateli
  • Každé view je jednoznačně identifikovatelné
  • Zobrazení korektného view zajišťuje viewResolver
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver getViewResolver() {

        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }
}

View

  • Jaké view se zobrazí rozhoduje controller
  • View dokáže číst data z předaného modelu
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
hello ${modelKey}
</body>
</html>
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String request(Model model) {

    model.addAttribute("modelKey", "testVal");
    return "hello";
}

hello.jsp

Spring MVC_cv

  • jednoduchá web app:
    • jeden controller
    • dvě view
    • použít model

Request parametry

  • @PathVariable - http://localhost:8080/hello/123
  • @RequestParam - http://localhost:8080/hello?id=123
  • @ModelAttribute - možno oboje
@RequestMapping(value = "/hello/{id}")
    public String request(@PathVariable("id") int id, Model model) {
}

@RequestMapping(value = "/hello")
    public String request(@RequestParam("id") int id, Model model) {
}

@RequestMapping(value = "/pet/{id}/{name}")
public String requestPet(@ModelAttribute("pet") Pet pet, Model model) {
}

@RequestMapping(value = "/pet")
public String requestPet(@ModelAttribute("pet") Pet pet, Model model) {
}

ModelAttribute

  • umožňuje vytvoření default hodnot pro model
@ModelAttribute("student")
private Student createStudent() {

    Student student = new Student();
    student.setUserName("default");
    student.setEmail("default_mail");

    return student;
}

@RequestMapping(value = "/student", method = RequestMethod.GET)
public String student(@ModelAttribute("student") Student student) {

    return "student";
}

Validace

  • využíváme validation-api + hibernate implementaci
  • @Valid:
    • přes anotace můžeme definovat některé restrikce na modelu
@NotNull
@Min(2)
private String userName;

@Size(min = 5, max = 10)
private String email;

public String addStudent(@Valid Student student, BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        System.out.println("ERROR");
    }
    ...
}

Validace

  • Pomocí vlastního validátoru - implementace 
    org.springframework.validation.Validator
@Override
public void validate(Object target, Errors errors) {

  Student2 student2 = (Student2) target;

  if (student2.getUserName().length() < 3) {
      errors.rejectValue("userName", "001", "username must have more than 3 char");
  }
}
@InitBinder("student2")
protected void initBinderStudent2(WebDataBinder webDataBinder) {

  webDataBinder.setValidator(studentValidator);
}

public String addStudent2(@ModelAttribute("student2") @Valid Student2 student,
    BindingResult bindingResult) {