跳至主要內容

Springboot-3.web开发

holic-x...大约 7 分钟框架Springboot

Springboot-web开发

SpringMVC的快速应用

1.基于restful http接口的CRUD

Result(接口响应格式定义)

public class Result<T> {
    private Integer code;
    private String message;
    private T data;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Result(Integer code, String message) {
        this.code = code;
        this.message = message;
    }


    public Result() {
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }
}

User

@Data
public class User {
    private Integer id;
    private String username;
    private String address;
    private Date birthday;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public User(Integer id, String username, String address) {
        this.id = id;
        this.username = username;
        this.address = address;
    }

    public User(String username, String address) {
        this.username = username;
        this.address = address;
    }

    public User(Integer id, String username, String address, Date birthday) {
        this.id = id;
        this.username = username;
        this.address = address;
        this.birthday = birthday;
    }

    public User() {
    }
}

UserService(模拟数据库操作)

@Component
public class UserService {
    private static Map<Integer, User> users = new HashMap<>();

    static {
        users.put(1, new User(1, "zhangsan", "北京", new Date()));
        users.put(2, new User(2, "lisi", "上海"));
        users.put(3, new User(3, "wangwu", "深圳"));
        users.put(4, new User(4, "xushu", "非洲"));
        users.put(5, new User(5, "zhuge", "塔寨村"));
    }

    /**
     * 根据id查询用户
     */
    public User getUserById(Integer id) {
        return users.get(id);
    }


    /**
     * 查询所有用户
     */
    public List<User> getAllUser() {
        return new ArrayList(users.values());
    }

    /**
     * 更新
     */
    public void update(User user) {
        users.replace(user.getId(), user);
    }


    /**
     * 新增
     */
    public void add(User user) {
        Integer newId = users.size() + 1;
        user.setId(newId);
        users.put(newId, user);
    }

    /**
     * 删除
     */
    public void delete(Integer id) {
        users.keySet().removeIf(key -> key == id);
    }

}

userController(接口定义)

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;

    // Rest  /user/1
    @GetMapping("/{id}")
    public Result getUser(@PathVariable Integer id) {
        User user = userService.getUserById(id);
        return new Result<>(200, "查询成功", user);
    }

    // 新增 /user/add
    @PostMapping("/add")
    public Result addUser(User user) {
        userService.add(user);
        return new Result<>(200, "添加成功");
    }

    // 修改 /user1
    @PutMapping("/{id}")
    public Result editUser(User user) {
        userService.update(user);
        return new Result<>(200, "修改成功");
    }

    // 修改 /user1
    @DeleteMapping("/{id}")
    public Result editUser(@PathVariable Integer id) {
        userService.delete(id);
        return new Result<>(200, "删除成功");
    }
}

项目启动访问:http://localhost:8080/user/1,检查响应结果

2.接口调用

调用rest http接口

​ RestTemplate是Spring提供的用于访问Rest服务的,RestTemplate提供了多种便捷访问远程Http服务的方法,传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient或者第三方工具类hutools的请求工具类。spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate。

​ 适用于微服务架构下 服务之间的远程调用 微服务架构(spring cloud feign)

WebClient 都可以调用远程服务,区别:webclient 依赖webflux , webclient 请求远程服务是无阻塞的,响应的。 RestTemplate 它是阻塞的,需要等待请求响应后才能执行下一句代码

通过测试类测试接口调用

@SpringBootTest
class SpringbootHelloworldApplicationTests {
    @Test
    void callByRestTemplate() {
        TestRestTemplate restTemplate = new TestRestTemplate();
        // 基于restTemplate 调用删除
        ResponseEntity<Result> resultResponseEntity = restTemplate.exchange("http://localhost:8080/user/{id}", HttpMethod.DELETE, null, Result.class, 1);
        System.out.println(resultResponseEntity.toString());
    }
}

通过postman调用

image-20240405133046999

通过MockMvc测试

HelloController

@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping("/getName")
    @ResponseBody
    public String getName(@RequestParam String name){
        return "Hello-" + name;
    }
}

​ MockMvc是由spring-test包提供,实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,使得测试速度快、不依赖网络环境。同时提供了一套验证的工具,结果的验证十分方便

​ 编写测试类。实例化MockMvc有两种形式,一种是使用StandaloneMockMvcBuilder,另外一种是使用DefaultMockMvcBuilder。测试类及初始化MockMvc初始化:

@SpringBootTest
@AutoConfigureMockMvc
class MockMvcExampleTests {

    @Test
    public void testHello(@Autowired MockMvc mockMvc) throws Exception {

        /*
         * 1、mockMvc.perform执行一个请求
         * 2、MockMvcRequestBuilders.get("XXX")构造一个请求
         * 3、ResultActions.param添加请求传值
         * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型
         * 5、ResultActions.andExpect添加执行完成后的断言
         * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情
         *   比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息
         * 7、ResultActions.andReturn表示执行完成后返回相应的结果
         */
        mockMvc.perform(MockMvcRequestBuilders
                .get("/hello/getName")
                // 设置返回值类型为utf-8,否则默认为ISO-8859-1
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .param("name", "Tom"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.content().string("Hello-Tom"))
                .andDo(MockMvcResultHandlers.print());
    }
}

image-20240405134714229

通过swagger调用

​ SpringBoot 整合swagger2.x ,自动生成接口文档

pom.xml依赖引入

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

配置swagger配置

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.noob.demo.controller"))
                .paths(PathSelectors.any())
                .build().apiInfo(new ApiInfoBuilder()
                        .title("SpringBoot整合Swagger")
                        .description("SpringBoot整合Swagger,详细信息......")
                        .version("1.0")
                        .contact(new Contact("noob", "blog.holic-x.com", "holic-x@foxmail.com"))
                        .build());
    }
}

项目启动配置出错,可能是由于springboot版本与swagger版本不兼容导致(springboot 升级到 2.6.0之后,swagger版本和springboot出现了不兼容情况),此处配置springboot-2.7.6、swagger-2.9.2

image-20240405140203048

解决方案:

【1】方案1:在项目配置类SwaggerConfig或者Springboot启动类中添加@EnableWebMvc注解

【2】方案2:在 application.properties 配置文件添加配置: properties spring.mvc.pathmatch.matching-strategy=ant_path_matcher

【3】方案3:降低配置确保兼容性,例如降低springboot版本为2.5.6

项目启动成功但是出现访问404,则需要自定义WebMvcConfig实现WebMvcConfig过滤静态资源文件

image-20240405141930193

​ 再次启动,尝试访问http://localhost:8080/swagger-ui.html

image-20240405141957800

SpringMVC自动配置原理分析

SpringMVC自动配置定制化

1.WebMvcConfigurer扩展

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    /**
     * 添加视图控制器
     * 立即访问
     * <mvc:view-controller path="/" view-name="index" />
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/tuling").setViewName("hello");
    }

    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TimeInterceptor())     //添加拦截器
            .addPathPatterns("/**")    // 拦截映射规则
            .excludePathPatterns("/pages/**");  // 设置排除的映射规则
    }

    /**
     * 全局CORS配置
     * @param registry

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/user/*")   // 映射服务器中那些http接口运行跨域访问
        .allowedOrigins("http://localhost:8081")     // 配置哪些来源有权限跨域
        .allowedMethods("GET","POST","DELETE","PUT");   // 配置运行跨域访问的请求方法
    }*/

}

实现WebMvcConfigurer接口可以扩展MVC实现, 又既保留SpringBoot的自动配置

(1)在WebMvcAutoConfiguration也有一个实现了WebMvcConfigurer的配置类

(2)WebMvcAutoConfigurationAdapter 它也是利用这种方式去进行扩展, 通过查看这个类发现它实现了其他不常用的方法,进行自动配置,只需定制(拦截器、视图控制器、CORS 在开发中需要额外定制的定制的功能)

@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}

2.Json开发

Spring Boot提供了与三个JSON映射库的集成:

  • Gson
  • Jackson 性能最好
  • JSON-B

Jackson 是使用的默认json库

jsckson的使用

  • @JsonIgnore:进行排除json序列化,将它标注在属性上将不会进行json序列化
  • @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh"):进行日期格式化
  • @JsonInclude(JsonInclude.Include.NON_NULL) :当属性值为null时则不进行json序列化
  • @JsonProperty("uname"):设置别名

SpringBoot 还提供了@JsonComponent 来根据自己的业务需求进行json的序列化和反序列化

@JsonComponent
public class UserJsonCustom {
    public static class Serializer extends JsonObjectSerializer<User> {
        @Override
        protected void serializeObject(User user, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeObjectField("id",user.getId());   //{"id","xxx"}
            jgen.writeObjectField("uname","xxxxx");
            /*jgen.writeFieldName("");  单独写key
            jgen.writeObject();   单独写value
            */
            // 1. 一次查不出完整的数据返回给客户端, 需要根据需求去做一些个性化调整
            // 2. 根据不同的权限给他返回不同的序列化数据
        }
    }

    public static class Deserializer extends JsonObjectDeserializer<User> {
        @Override
        protected User deserializeObject(JsonParser jsonParser, DeserializationContext context, ObjectCodec codec, JsonNode tree) throws IOException {
            User user=new User();
            user.setId(tree.findValue("id").asInt());

            return user;
        }
    }
}

3.国际化

添加国际化资源文件resource

配置messageResource设置国际化资源文件

在Springboot中提供了MessageSourceAutoConfiguration,不需要去配置messageResource,但是它并生效:开启debug=true

4.统一异常处理

SpringBoot 有统一异常处理自动配置类:ErrorMvcAutoConfiguration统一异常处理自动配置类

重要组件:DefaultErrorAttributes、BasicErrorController、DefaultErrorViewResolver(解析错误视图页面)

BasicErrorController:处理/error请求的一个控制器

image-20240405160031214

Springboot的嵌入式Servlet容器

1.嵌入式Servlet容器配置修改

2.注册servlet三大组件

3.切换其他嵌入式Servlet容器

4.嵌入式Servlet容器自动配置原理 SpringBoot 2.3.6

5.使用外部Servlet容器

6.外部Servlet容器启动SpringBoot应用原理

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3