Spring Boot基础功能: 路由
基于@RequestMapping注解的路由
package com.sniucom.controller
import org.springframework.stereotype.RequestController;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public String single(@PathVariable Long id)
{
...
}
@RequestMapping(method=RequestMethod.GET)
public String lists()
{
...
}
@RequestMapping(value="{id}", method=RequestMethod.DELETE)
public String destory(@PathVariable Long id)
{
....
}
}
可用HTTP方法包含
- RequestMethod.GET
- RequestMethod.POST
- RequestMethod.PUT
- RequestMethod.PATCH
- RequestMethod.DELETE
- RequestMethod.HEAD
- RequestMethod.TRACE
对Controller类使用注解@RequestMapping("/user"),可设置URL前缀
方法注解
- @GetMapping
- @PostMapping
- @PutMapping
- @PathMapping
- @DeleteMapping
- @HeadMapping
- @TraceMapping
较为简单方便
接口路由的版本控制
对controller增加
@RequestMapping("/v2/user")
全局路径配置
server:
servlet:
context-path: /prefix
自定义注解实现前缀
先撞见一个自定义注解
package com.juhedao.nosocomium.application.common;
import org.springframework.core.annotation.AliasFor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RestController
@RequestMapping
public @interface ApiRestController {
/**
* Alias for {@link RequestMapping#name}.
*/
@AliasFor(annotation = RequestMapping.class)
String name() default "";
/**
* Alias for {@link RequestMapping#value}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
/**
* Alias for {@link RequestMapping#path}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
}
添加一个配置
package com.juhedao.nosocomium.application.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.juhedao.nosocomium.application.common.ApiRestController;
@Configuration
public class ApiConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("/api", c -> c.isAnnotationPresent(ApiRestController.class));
//.addPathPrefix("/api/v2", c -> c.isAnnotationPresent(ApiV2RestController.class));
}
}
使用
package com.juhedao.nosocomium.application.controller.api;
import com.juhedao.nosocomium.application.common.ApiRestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@ApiRestController(value={"/administrator"})
public class Administrator {
@GetMapping("")
public String index()
{
return "爱吃鱼的大脸猫";
}
@GetMapping("/{id}")
public String show(@PathVariable Integer id)
{
return "采蘑菇的小姑娘";
}
}
按照目录结构包名添加前缀
配置 application.yml
# 需要添加路径前缀的包名
api-package: com.example.demo.controller
AutoPrefixUrlMapping.java
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* 自动补全路由前缀处理类
*/
public class AutoPrefixUrlMapping extends RequestMappingHandlerMapping {
/**
* 读取基础包配置
*/
@Value("${api-package}")
private String bathApiPackagePath;
/**
* 重写方法路由获取
*
* @param method
* @param handlerType
* @return
*/
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo mappingInfo = super.getMappingForMethod(method, handlerType);
if (Objects.nonNull(mappingInfo)) {
String prefix = this.getPrefix(handlerType);
if (prefix != null) {
String[] paths = mappingInfo.getPatternValues()
.stream()
.map(path -> prefix + path)
.toArray(String[]::new);
return mappingInfo.mutate()
.paths(paths)
.build();
}
}
return mappingInfo;
}
/**
* 获取方法路由前缀
*
* @param handleType
* @return
*/
private String getPrefix(Class<?> handleType) {
String packageName = handleType.getPackage().getName();
// 如果包含指定的包则返回前缀
if (packageName.startsWith(this.bathApiPackagePath)) {
return packageName.substring(this.bathApiPackagePath.length())
.replace(".", "/");
} else {
return null;
}
}
}
控制器
package com.example.demo.controller.v1;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class IndexController {
@GetMapping("/index")
public String index() {
return "Hello";
}
}
发表回复