服务端开发(2) Web MVC
2023-08-09 14:53:19 # NJU # 服务端开发

Taco示例

1. lombok

编译期后就不需要了,要排除

1
2
3
4
5
6
7
8
9
10
11
12
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>

2. DesignTacoController控制器实现

1
2
3
4
5
6
7
8
9
10
11
@Slf4j
@Controller
@RequestMapping("/design")
@SessionAttributes("tacoOrder")
public class DesignTacoController {
...
/** @Slf4j 可替代
* private static final org.slf4j.Logger log =
* org.slf4j.LoggerFactory.getLogger(DesignTacoController.class);
*/
}

3. Spring MVC的请求映射注解

1
2
3
4
5
6
@RequestMapping
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

4. 设计视图

使用 thymeleaf

5. 处理表单提交

5.1 Converter

前端返回的是String, 后端需要的是 Ingredient, 如何解决

1
2
<input th:field="*{ingredients}" type="checkbox" 
th:value="${ingredient.id}"/>
1
2
3
@NotNull
@Size(min=1, message="You must choose at least 1 ingredient")
private List<Ingredient> ingredients;

使用 Spring 提供的 Converter 来解决

1
2
3
4
5
6
7
8
9
10
@Component
public class IngredientByIdConverter implements Converter<String, Ingredient> {

private Map<String, Ingredient> ingredientMap = new HashMap<>();

@Override
public Ingredient convert(String id) {
return ingredientMap.get(id);
}
}

5.2 rediect重定向

1
return "redirect:/orders/current";

image-20230302210339075

6. 校验表单输入

  • JavaBean Validation API
  • spring-boot-starter-validation
  • 领域类上添加校验规则
  • 控制器中声明校验:@Valid
  • 修改表单视图以展现校验错误
1
2
3
4
5
6
7
8
9
10
11
12
@Data
public class Taco {

@NotNull
@Size(min=5, message="Name must be at least 5 characters long")
private String name;

@NotNull
@Size(min=1, message="You must choose at least 1 ingredient")
private List<Ingredient> ingredients;

}
1
2
3
4
5
6
@PostMapping
public String processTaco(@Valid Taco taco,
Errors errors,
@ModelAttribute TacoOrder tacoOrder) {
...
}

7. 使用视图控制器

  • 接口 WebMvcConfigurer,用于配置
  • 简单的从请求URL到视图
    • registry.addViewController("/").setViewName("home");
    • 如果路径是 “/“, 直接返回 home 视图