看看第一个controller
@Controller
public class HelloController {
@GetMapping("/hello")
public String handle(Model model) {
model.addAttribute("message", "Hello World!");
return "index";
}
}
上面透漏一下信息:是一个GET响应 查找web下的index模版,通过model将数据传递给模版引擎渲染
我们看到了能访问/hello,那么为啥呢?SpringMVC怎么知道有这个文件呢?--答案是通过组件扫描
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {
// ...
}
上面的代码与xml配置等同
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example.web"/>
<!-- ... -->
</beans>
总体来说都是基于Spring的IOC容器方式,通过组件扫描将各组件加载称为bean
采用@Request Mapping实现controller响应controllers的网络请求
下面是具体分类,来响应区分不同的网络方法
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
下面是具体的实例参考
@RestController
@RequestMapping("/persons")
class PersonController {
@GetMapping("/{id}")
public Person getPerson(@PathVariable Long id) {
// ...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// ...
}
}
可以使用@PathVariable匹配参数中添加变量参数来区分数据,比如
@GetMapping("/owners/{ownerId}/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
同时你也能够在class和Method级别注解声明URI变量,比如
@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {
@GetMapping("/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
}
上面中controller下的所有Mapping响应都会加上/owners/{ownerId}前缀,例如上栗中的组合成为:/owners/{ownerId}/pets/{petId}
除此紫外我们还可在Mapping中添加正则匹配:
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String ext) {
// ...
}
在Mapping注解中我们还可以限制Content-Type
@PostMapping(path = "/pets", consumes = "application/json")
public void addPet(@RequestBody Pet pet) {
// ...
}
还可以设置header数据
@GetMapping(path = "/pets", headers = "myHeader=myValue")
public void findPet(@PathVariable String petId) {
// ...
}
动态注册Controller响应
@Configuration
public class MyConfig {
@Autowired
public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler)
throws NoSuchMethodException {
RequestMappingInfo info = RequestMappingInfo
.paths("/user/{id}").methods(RequestMethod.GET).build();
Method method = UserHandler.class.getMethod("getUser", Long.class);
mapping.registerMapping(info, handler, method);
}
}
请求参数
在方法中使用@RequestParam只标注的变量是url中的query数据
@Controller
@RequestMapping("/pets")
public class EditPetForm {
@GetMapping
public String setupForm(@RequestParam("petId") int petId, Model model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
}
上栗中的urlquery为:/pets?petId=xxx
与此同时我还可以使用@RequestHeader将header的数据注入到响应的方法中
@GetMapping("/demo")
public void handle(
@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {
//...
}
Session和Cookie注入
@GetMapping("/demo")
public void handle(@CookieValue("JSESSIONID") String cookie) {
//...
}
@RequestMapping("/")
public String handle(@SessionAttribute User user) {
// ...
}
请求数据转模型注入(@ModelAttribute
)
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet, BindingResult result) {
if (result.hasErrors()) {
return "petForm";
}
}
这个需要请求参数与Model的属性名称相同,也是十分方便,同时也可做数据监测
文件上传
文件上传通常采用form表单需要multipart/form-data
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
同样的我们也可将form的文件转换为model
class MyForm {
private String name;
private MultipartFile file;
// ...
}
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(MyForm form, BindingResult errors) {
if (!form.getFile().isEmpty()) {
byte[] bytes = form.getFile().getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
这个form文件上传会有两个字段:一个是表单名 另一个是文件名
今天就这么多,看英文自己翻译总结还是费点劲,下一篇阅读URL Linkes