精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringBoot3之Web編程

開發 前端
在個人的習慣上,Swagger接口文檔更偏向在前后端對接的時候使用,而Junit單元測試更符合開發的時候使用,這里是對RestWeb中的接口進行測試。

一、簡介

基于web包的依賴,SpringBoot可以快速啟動一個web容器,簡化項目的開發;

在web開發中又涉及如下幾個功能點:

攔截器:可以讓接口被訪問之前,將請求攔截到,通過對請求的識別和校驗,判斷請求是否允許通過;

頁面交互:對于服務端的開發來說,需要具備簡單的頁面開發能力,解決部分場景的需求;

Swagger接口:通過簡單的配置,快速生成接口的描述,并且提供對接口的測試能力;

Junit測試:通過編寫代碼的方式對接口進行測試,從而完成對接口的檢查和驗證,并且可以不入侵原代碼結構;

二、工程搭建

1、工程結構

圖片圖片

2、依賴管理

<!-- 基礎框架組件 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>${spring-boot.version}</version>
</dependency>
<!-- 接口文檔組件 -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>${springdoc.version}</version>
</dependency>
<!-- 前端頁面組件 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>${spring-boot.version}</version>
</dependency>
<!-- 單元測試組件 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>${spring-boot.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
</dependency>

三、Web開發

1、接口開發

編寫四個簡單常規的接口,從對資源操作的角度,也就是常說的:增Post、刪Delete、改Put、查Get,并且使用了swagger注解,可以快速生成接口文檔;

@RestController
@Tag(name = "Rest接口")
public class RestWeb {

    @Operation(summary = "Get接口")
    @GetMapping("rest/get/{id}")
    public String restGet(@PathVariable Integer id) {
        return "OK:"+id;
    }

    @Operation(summary = "Post接口")
    @PostMapping("/rest/post")
    public String restPost(@RequestBody ParamBO param){
        return "OK:"+param.getName();
    }

    @Operation(summary = "Put接口")
    @PutMapping("/rest/put")
    public String restPut(@RequestBody ParamBO param){
        return "OK:"+param.getId();
    }

    @Operation(summary = "Delete接口")
    @DeleteMapping("/rest/delete/{id}")
    public String restDelete(@PathVariable Integer id){
        return "OK:"+id;
    }
}

2、頁面交互

對于服務端開發來說,在部分場景下是需要進行簡單的頁面開發的,比如通過頁面渲染再去生成文件,或者直接通過頁面填充郵件內容等;

數據接口

@Controller
public class PageWeb {

    @RequestMapping("/page/view")
    public ModelAndView pageView (HttpServletRequest request){
        ModelAndView modelAndView = new ModelAndView() ;
        // 普通參數
        modelAndView.addObject("name", "cicada");
        modelAndView.addObject("time", "2023-07-12");
        // 對象模型
        modelAndView.addObject("page", new PageBO(7,"頁面數據模型"));
        // List集合
        List<PageBO> pageList = new ArrayList<>() ;
        pageList.add(new PageBO(1,"第一頁"));
        pageList.add(new PageBO(2,"第二頁"));
        modelAndView.addObject("pageList", pageList);
        // Array數組
        PageBO[] pageArr = new PageBO[]{new PageBO(6,"第六頁"),new PageBO(7,"第七頁")} ;
        modelAndView.addObject("pageArr", pageArr);
        modelAndView.setViewName("/page-view");
        return modelAndView ;
    }
}

頁面解析:分別解析了普通參數,實體對象,集合容器,數組容器等幾種數據模型;

<div style="text-align: center">
    <hr/>
    <h5>普通參數解析</h5>
    姓名:<span th:text="${name}"></span>
    時間:<span th:text="${time}"></span>
    <hr/>
    <h5>對象模型解析</h5>
    整形:<span th:text="${page.getKey()}"></span>
    字符:<span th:text="${page.getValue()}"></span>
    <hr/>
    <h5>集合容器解析</h5>
    <table style="margin:0 auto;width: 200px">
        <tr>
            <th>Key</th>
            <th>Value</th>
        </tr>
        <tr th:each="page:${pageList}">
            <td th:text="${page.getKey()}"></td>
            <td th:text="${page.getValue()}"></td>
        </tr>
    </table>
    <hr/>
    <h5>數組容器解析</h5>
    <table style="margin:0 auto;width: 200px">
        <tr>
            <th>Key</th>
            <th>Value</th>
        </tr>
        <tr th:each="page:${pageArr}">
            <td th:text="${page.getKey()}"></td>
            <td th:text="${page.getValue()}"></td>
        </tr>
    </table>
    <hr/>
</div>

效果圖展示

圖片圖片

四、攔截器

1、攔截器定義

通過實現HandlerInterceptor接口,完成對兩個攔截器的自定義,請求在訪問服務時,必須通過兩個攔截器的校驗;

/**
 * 攔截器一
 */
public class HeadInterceptor implements HandlerInterceptor {
    private static final Logger log  = LoggerFactory.getLogger(HeadInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        log.info("HeadInterceptor:preHandle");
        Iterator<String> headNames = request.getHeaderNames().asIterator();
        log.info("request-header");
        while (headNames.hasNext()){
            String headName = headNames.next();
            String headValue = request.getHeader(headName);
            System.out.println(headName+":"+headValue);
        }
        // 放開攔截
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        log.info("HeadInterceptor:postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,
                                Object handler, Exception e) throws Exception {
        log.info("HeadInterceptor:afterCompletion");
    }
}

/**
 * 攔截器二
 */
public class BodyInterceptor implements HandlerInterceptor {
    private static final Logger log  = LoggerFactory.getLogger(BodyInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,
                             Object handler) throws Exception {
        log.info("BodyInterceptor:preHandle");
        Iterator<String> paramNames = request.getParameterNames().asIterator();
        log.info("request-param");
        while (paramNames.hasNext()){
            String paramName = paramNames.next();
            String paramValue = request.getParameter(paramName);
            System.out.println(paramName+":"+paramValue);
        }
        // 放開攔截
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        log.info("BodyInterceptor:postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,
                                Object handler, Exception e) throws Exception {
        log.info("BodyInterceptor:afterCompletion");
    }
}

2、攔截器配置

自定義攔截器之后,還需要添加到web工程的配置文件中,可以通過實現WebMvcConfigurer接口,完成自定義的配置添加;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 添加自定義攔截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HeadInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new BodyInterceptor()).addPathPatterns("/**");
    }
}

五、測試工具

1、Swagger接口

添加上述的springdoc依賴之后,還可以在配置文件中簡單定義一些信息,訪問IP:端口/swagger-ui/index.html即可;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 接口文檔配置
     */
    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info().title("【boot-web】").description("Rest接口文檔-2023-07-11")
                .version("1.0.0"));
    }
}

圖片圖片

2、Junit測試

在個人的習慣上,Swagger接口文檔更偏向在前后端對接的時候使用,而Junit單元測試更符合開發的時候使用,這里是對RestWeb中的接口進行測試;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class RestWebTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGet () throws Exception {
        // GET接口測試
        MvcResult mvcResult = mockMvc
                .perform(MockMvcRequestBuilders.get("/rest/get/1"))
                .andReturn();
        printMvcResult(mvcResult);
    }

    @Test
    public void testPost () throws Exception {
        // 參數模型
        JsonMapper jsonMapper = new JsonMapper();
        ParamBO param = new ParamBO(null,"單元測試",new Date()) ;
        String paramJson = jsonMapper.writeValueAsString(param) ;
        // Post接口測試
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/rest/post")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON).content(paramJson)).andReturn();
        printMvcResult(mvcResult);
    }

    @Test
    public void testPut () throws Exception {
        // 參數模型
        JsonMapper jsonMapper = new JsonMapper();
        ParamBO param = new ParamBO(7,"Junit組件",new Date()) ;
        String paramJson = jsonMapper.writeValueAsString(param) ;
        // Put接口測試
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.put("/rest/put")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON).content(paramJson)).andReturn();
        printMvcResult(mvcResult);
    }

    @Test
    public void testDelete () throws Exception {
        // Delete接口測試
        MvcResult mvcResult = mockMvc
                .perform(MockMvcRequestBuilders.delete("/rest/delete/2"))
                .andReturn();
        printMvcResult(mvcResult);
    }

    /**
     * 打印【MvcResult】信息
     */
    private void printMvcResult (MvcResult mvcResult) throws Exception {
        System.out.println("請求-URI【"+mvcResult.getRequest().getRequestURI()+"】");
        System.out.println("響應-status【"+mvcResult.getResponse().getStatus()+"】");
        System.out.println("響應-content【"+mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8)+"】");
    }
}

六、參考源碼

文檔倉庫:
https://gitee.com/cicadasmile/butte-java-note

源碼倉庫:
https://gitee.com/cicadasmile/butte-spring-parent
責任編輯:武曉燕 來源: 知了一笑
相關推薦

2023-08-07 14:28:07

SpringBoot工具

2023-08-11 08:59:49

分庫分表數據數據庫

2024-10-08 08:26:43

2024-07-31 14:03:00

Spring定時任務管理

2023-08-08 08:23:08

Spring日志?線程池

2024-09-11 09:15:06

2023-06-19 08:05:17

RFCwebSpring

2024-03-04 08:19:11

SpringURLHeader

2024-05-10 08:10:05

Spring虛擬線程JDK

2023-05-10 11:34:06

springboot日志服務器

2023-02-01 10:40:01

2014-04-28 10:26:33

編程Web編程

2024-01-31 08:26:44

2022-01-27 23:39:46

Java17版本Spring

2022-07-04 10:34:45

編程語言RustGo

2020-03-03 19:24:30

Web服務器ApacheTomcat

2010-11-25 09:06:37

Web開發函數式編程

2025-04-16 10:03:40

開發Spring應用程序

2021-09-09 12:28:50

Sentry Web性能監控

2025-06-26 04:10:00

點贊
收藏

51CTO技術棧公眾號

全球中文成人在线| avav免费在线观看| 99在线热播精品免费99热| 精品香蕉在线观看视频一| 日本老熟妇毛茸茸| 在线观看小视频| 26uuu成人网一区二区三区| 国产精品永久在线| 中日韩精品视频在线观看| 欧美日韩在线播放视频| 欧美xxxxxxxxx| 青青草av网站| 91老司机福利在线| 国产精品久久久久久久久免费桃花| 亚洲一区二区日本| 精品黑人一区二区三区| 欧美精品色网| 一区二区三区视频免费| 在线看黄色的网站| 96sao精品免费视频观看| 疯狂欧美牲乱大交777| 亚洲区成人777777精品| se在线电影| av在线播放一区二区三区| 国产日产亚洲精品| 久久中文字幕免费| 伊人激情综合| 久久国产精品久久久久| 日韩免费成人av| 欧美一区 二区| 欧美mv和日韩mv国产网站| 在线看的黄色网址| 久久人体大尺度| 亚洲成人综合网站| 91精品一区二区三区四区| 成人亚洲性情网站www在线观看| 成人午夜又粗又硬又大| 91传媒视频免费| 国产男男gay体育生白袜| 蜜桃视频在线一区| 国产ts人妖一区二区三区| 国产无遮无挡120秒| 自拍欧美日韩| 久久精品视频va| 日韩欧美黄色网址| av在线不卡顿| 中文日韩在线观看| 五月婷婷六月香| 精品日本12videosex| 亚洲人成啪啪网站| 成人片黄网站色大片免费毛片| 青草久久视频| 日韩精品视频在线观看免费| 少妇被狂c下部羞羞漫画| 国产精品调教| 亚洲国产精品va在线看黑人动漫 | 日韩中文视频| 欧美性猛交xxxxx水多| 国产超级av在线| 韩日成人影院| 欧美性大战久久久久久久| 国产天堂在线播放| 欧美影视资讯| 欧美日韩国产在线观看| 亚洲第一色av| 日韩中文字幕无砖| 亚洲国产高潮在线观看| 全黄一级裸体片| 日韩电影免费网站| 久久艳片www.17c.com| 久久机热这里只有精品| 国产日韩欧美三级| 日韩av不卡电影| 中文资源在线播放| 国产美女在线精品| 国产一区二区无遮挡| 天天摸天天碰天天爽天天弄| 久久亚洲捆绑美女| 台湾成人av| 国产三区在线观看| 午夜视频久久久久久| 成人一级片网站| 久久久久久久性潮| 欧美成人精品3d动漫h| aa片在线观看视频在线播放| 欧美日韩在线二区| 欧美高清电影在线看| 91porny在线| 久久精品国产999大香线蕉| 亚洲在线一区二区| 精品三级久久久久久久电影聊斋| 中文字幕中文在线不卡住| 国产夫妻自拍一区| 精品国产欧美日韩一区二区三区| 91精品国产色综合久久ai换脸 | 国产精品电影一区二区三区| gogogo免费高清日本写真| 国产粉嫩在线观看| 欧美日韩另类一区| 免费黄色三级网站| 91亚洲人成网污www| 欧美激情视频一区二区| 制服丝袜在线一区| 99热精品国产| 欧洲xxxxx| 91精品影视| 日韩精品一区二区三区在线| 精品无码国产污污污免费网站| 欧美99久久| 国产精品久久久久久久久久久新郎 | 日韩福利在线| av有码在线观看| 欧美美女喷水视频| 亚洲午夜福利在线观看| 午夜欧美理论片| 国产乱肥老妇国产一区二| 五月天婷婷社区| 亚洲精品免费在线播放| the porn av| 最近国产精品视频| 久久人91精品久久久久久不卡| 亚洲在线视频播放| 国产欧美一二三区| 日韩av片在线看| 一本一道久久a久久| 久久精品成人动漫| 啪啪小视频网站| 粉嫩av一区二区三区四区五区| 亚洲不卡一区二区三区| 中文字幕12页| 日韩情爱电影在线观看| 国产精品久久久久久久久久小说| 天天干天天爱天天操| 亚洲一区二区三区三| 两女双腿交缠激烈磨豆腐| 久久看人人摘| 国产精品自拍偷拍| 春暖花开成人亚洲区| 91国产成人在线| 偷拍夫妻性生活| 午夜综合激情| 久久资源av| 六月婷婷综合| 亚洲天堂男人天堂女人天堂| 欧美精品一二三四区| 久久综合成人精品亚洲另类欧美| 精品国产av无码一区二区三区| 亚洲精品影片| 欧美华人在线视频| 你懂的网站在线| 亚洲成人一区在线| 亚洲香蕉中文网| 999在线观看精品免费不卡网站| 官网99热精品| free性m.freesex欧美| 亚洲国产精彩中文乱码av| 国偷自拍第113页| 久久―日本道色综合久久| 国产精品亚洲αv天堂无码| 色综合综合色| 国产精品成人免费电影| 午夜免费福利在线观看| 51午夜精品国产| 青娱乐91视频| kk眼镜猥琐国模调教系列一区二区| 成人免费视频91| 伊人久久大香线蕉av不卡| 国产精品久久久久久久午夜| 色综合久久影院| 欧美不卡一区二区三区四区| www.日本精品| 国产精品天美传媒| 精品国产午夜福利在线观看| 亚洲激情网站| 亚洲国产日韩欧美| 日本一区二区三区播放| 97精品视频在线| 成年网站在线| 精品女同一区二区| 一级片视频在线观看| 中文字幕日本不卡| 午夜免费福利影院| 老司机午夜精品视频| 少妇熟女一区二区| 欧美日韩看看2015永久免费| 国产精品青青在线观看爽香蕉| 91蜜桃在线视频| 亚洲精品中文字幕女同| 国产精品综合在线| 午夜精品一区二区三区电影天堂| 成人无码av片在线观看| 国产91精品入口| 狠狠热免费视频| 黄色精品免费| 亚洲欧美久久234| 成人av婷婷| 国产精品美女无圣光视频| 91精品久久久| 中文一区二区视频| 亚洲人妻一区二区| 日韩午夜电影av| 不卡av电影在线| 亚洲国产色一区| 九九这里只有精品视频| 91美女在线观看| 亚洲午夜精品在线观看| 日本欧美一区二区三区乱码| 97视频在线免费| 久久精品免费一区二区三区| 欧美激情第六页| 中文字幕久久精品一区二区| 国产精品免费视频xxxx| 亚洲天堂电影| 久久久免费观看视频| 黄色网址在线免费观看| 国产小视频91| 瑟瑟在线观看| 精品国产自在久精品国产| 国产精品丝袜黑色高跟鞋| 在线欧美日韩精品| 亚洲国产成人无码av在线| 亚洲成人综合在线| 久久久久久久久久久久久久免费看| 欧美国产欧美综合| 在线免费观看成年人视频| 丁香桃色午夜亚洲一区二区三区| 性欧美1819| 日本午夜精品一区二区三区电影| 国产精品免费入口| 亚洲免费成人| 男人天堂a在线| 欧美色一级片| www婷婷av久久久影片| 91精品蜜臀一区二区三区在线| 亚洲国产一区二区精品视频 | 国产精品第56页| 亚洲午夜精品17c| 久久久久久久黄色| 一级做a爱片久久| 欧美成人黄色网| 亚洲久本草在线中文字幕| 成人在线观看小视频| 亚洲视频一区二区在线| 欧美一级特黄高清视频| 亚洲欧洲精品天堂一级| a一级免费视频| 国产精品初高中害羞小美女文| 在线观看天堂av| 国产精品久久久久精k8 | 日韩免费在线| 中文字幕久精品免| 婷婷综合在线| 成人毛片100部免费看| 欧美激情视频一区二区三区在线播放| 在线观看视频黄色| 欧美日韩91| av在线播放天堂| 久久动漫亚洲| 亚洲一二三区av| 韩国成人福利片在线播放| 视频区 图片区 小说区| 国产成人av一区二区三区在线| 亚洲国产精品第一页| 91首页免费视频| av电影网站在线观看| 国产精品国产三级国产三级人妇| 小向美奈子av| 亚洲一区二区高清| www.国产色| 欧美三级资源在线| 精品人妻无码一区二区| 欧美精品一区二区三| 久久久久久青草| 日韩网站在线观看| 波多野结衣精品| 国产999精品久久久影片官网| 国精品产品一区| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | 亚洲精品国产片| 亚洲欧美在线免费观看| 日韩欧美小视频| 久久人人爽人人爽人人片av高清| av日韩电影| 51国产成人精品午夜福中文下载| 日韩精品欧美大片| 中日韩在线视频| 一区二区三区国产在线| 天天爽夜夜爽一区二区三区| 国产成人在线免费| 男人的天堂av网| 亚洲高清一区二区三区| 真实的国产乱xxxx在线91| 亚洲精品在线免费观看视频| eeuss影院在线播放| 久久久久久久久久久av| 黄色精品视频| 国精产品一区二区| 久久中文亚洲字幕| 黄色大片在线免费看| 国产一区久久久| 日韩精品无码一区二区三区久久久 | 快播亚洲色图| 欧美黄免费看| 一区二区三区视频在线观看免费| 处破女av一区二区| 精品在线观看一区| 黑人巨大精品欧美一区二区一视频| 一级特黄色大片| 亚洲欧美在线一区| 91九色国产在线播放| 成人深夜直播免费观看| 精品日韩一区| 人妻内射一区二区在线视频| 粉嫩蜜臀av国产精品网站| 久久久久人妻一区精品色| 色综合天天狠狠| 亚洲第九十九页| 日韩视频免费看| 视频一区在线免费看| 久久精品美女| 影音先锋久久| 免费黄色av网址| 亚洲靠逼com| 一二三四区在线| 中文精品99久久国产香蕉| 午夜日韩成人影院| 久久一区二区精品| 99精品99| 一本加勒比波多野结衣| 亚洲夂夂婷婷色拍ww47| av无码精品一区二区三区宅噜噜| 色视频www在线播放国产成人 | 91精品国产综合久久久久久丝袜 | 妖精视频一区二区三区| 亚洲熟妇av日韩熟妇在线| 成人深夜福利app| 国产波霸爆乳一区二区| 欧美精品高清视频| 在线免费黄色| 国产在线观看91精品一区| 成人影视亚洲图片在线| 欧美精品性生活| 国产精品久久久久影院色老大| 国产一级片免费在线观看| 亚洲欧美日本精品| 日韩经典一区| 亚洲国产一区二区精品视频| 六月丁香综合在线视频| 亚洲少妇xxx| 91精品国产福利在线观看| 成人在线播放| 成人欧美一区二区三区视频| 欧美三级乱码| 亚洲av网址在线| 欧美性猛交xxxx乱大交3| 国产一级片在线| 国产精品日韩在线观看| 色狮一区二区三区四区视频| 可以看污的网站| 亚洲黄网站在线观看| 日本高清视频www| 欧美亚洲一区在线| 热久久天天拍国产| 亚洲第一天堂久久| 亚洲最大成人综合| 天堂а√在线8种子蜜桃视频| 国产成人精品在线观看| 国产精品videosex性欧美| 极品人妻一区二区| 欧美日韩国产综合视频在线观看中文| 美女做暖暖视频免费在线观看全部网址91 | 精品一区二区三区在线观看视频| 4444在线观看| 91丝袜美腿高跟国产极品老师| 波多野结衣爱爱| 另类图片亚洲另类| 亚洲第一二三区| mm131亚洲精品| 亚洲国产一区二区视频| 视频在线观看你懂的| 国产狼人综合免费视频| 亚洲国产99| 手机av在线不卡| 亚洲аv电影天堂网| 中文另类视频| www.国产在线视频| 欧美激情综合五月色丁香| 精品人妻一区二区三区浪潮在线 | 日韩黄色片在线| 久久久99免费| 亚洲精品一区二区三区不卡| 国产成人精品av在线| 午夜电影亚洲| 日韩精品电影一区二区三区| 精品国产电影一区二区| 成人国产网站| 久久久久免费看黄a片app| 亚洲三级久久久| 经典三级在线| 国内精品二区|