成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot 開發 Web 系統,快速入門指南!

開發 前端
在傳統的 Java web 工程中,通常會采用 JSP 來編寫頁面并進行數據展示。而在 Spring Boot 框架中,推薦使用 Thymeleaf 模板引擎來開發 Web 頁面。

01、背景介紹

在之前的文章中,我們簡單的介紹了 SpringBoot 項目的創建過程,了解了 Spring Boot 開箱即用的特性,本篇文章接著上篇的內容繼續介紹 Spring Boot 用于 web 工程開發時的其它特性。

廢話不多說了,上代碼!

02、應用實踐

當將 SpringBoot 框架用于傳統的 web 項目開發時,通常分為以下三個過程來實現。

  • 第一步:連接數據庫,實現對表進行 CRUD 操作
  • 第二步:引入模板引擎來開發頁面
  • 第三步:使用一些常見的 web 特性來滿足其它的功能開發

最后源碼目錄結構如下!

springboot-hello
├── src
│   └── main
│       ├── java
│          ├── com
│             ├── example
│                ├── springboot
│                   ├── Application.java
│                   ├── entity
│                      ├── User.java
│                   ├── service
│                      ├── UserService.java
│                   ├── web
│                      ├── UserController
│       └── resources
│           ├── application.properties
│           ├── templates
│           └─── index.html
└── pom.xml

下面我們依次來看看相關的實踐過程。

2.1、數據庫操作

這里我們以 Mysql 數據庫為例,采用 Spring 的 JdbcTemplate 模板來操作數據的的增刪改查,過程如下。

2.1.1、準備數據庫表

先創建tb_user表,包含屬性id、name、age,可以通過執行下面的建表語句。

CREATE TABLE `tb_user` (
  `id` bigint(20) unsigned NOT NULL,
  `name` varchar(30) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.1.2、添加相關依賴包

在我們訪問數據庫的時候,需要先配置一個數據庫驅動包,通常采用 JDBC 方式方式訪問,需要在pom.xml中引入相關依賴包。

<!--spring jdbc-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mysql 驅動-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2.1.3、添加數據源配置

與此同時,還需要在application.properties文件中配置相關的數據源訪問地址。

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

2.1.4、編寫領域對象

根據數據庫中創建的 User 表,創建對應的領域對象。

package com.example.springboot.entity;

public class User {

    /**
     * 用戶ID
     */
    private Long id;

    /**
     * 用戶名稱
     */
    private String name;

    /**
     * 用戶年齡
     */
    private Integer age;

    // set、get方法等...
}

2.1.5、編寫數據訪問對象

通過JdbcTemplate實現對tb_user表中的數據訪問操作。

package com.example.springboot.service;

@Service
public class UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查詢用戶
     * @return
     */
    public List<User> getAll() {
        List<User> users = jdbcTemplate.query("select id, name, age from tb_user", (resultSet, i) -> {
            User user = new User();
            user.setId(resultSet.getLong("id"));
            user.setName(resultSet.getString("name"));
            user.setAge(resultSet.getInt("age"));
            return user;
        });
        return users;
    }

    /**
     * 通過ID查詢用戶
     * @param id
     * @return
     */
    public User getById(Long id) {
        User target = jdbcTemplate.queryForObject("select id, name, age from tb_user where id = ?", new BeanPropertyRowMapper<User>(User.class),id);;
        return target;
    }

    /**
     * 創建用戶
     * @param entity
     * @return
     */
    public int create(User entity){
        return jdbcTemplate.update("insert into tb_user(id, name, age) values(?, ?, ?)", entity.getId(), entity.getName(), entity.getAge());
    }

    /**
     * 修改用戶
     * @param entity
     * @return
     */
    public int updateById(User entity){
        return jdbcTemplate.update("update tb_user set  name = ?, age = ? where id = ? ", entity.getName(), entity.getAge(), entity.getId());
    }


    /**
     * 刪除用戶
     * @param id
     * @return
     */
    public int deleteById(Long id) {
        return jdbcTemplate.update("delete from tb_user where id = ?", id);
    }
}

2.1.6、編寫單元測試用例

在src/test/java目錄下,編寫單元測試用例,驗證代碼中的增、刪、改、查操作的正確性,包名與主目錄中保持一致。

package com.example.springboot;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void test(){
        // 插入5條數據
        userService.create(new User(1L, "張三", 20));
        userService.create(new User(2L, "李四", 21));
        userService.create(new User(3L, "王五", 22));

        // 查詢全部數據
        List<User> dbList1 = userService.getAll();
        System.out.println("第一次全量查詢結果:" + dbList1.toString());

        // 修改數據
        userService.updateById(new User(2L, "趙六", 21));

        // 查詢指定數據
        User updateObj = userService.getById(2l);
        System.out.println("查詢[id=2]結果:" + updateObj.toString());

        // 刪除數據
        userService.deleteById(2L);
        userService.deleteById(3L);

        // 查詢全部數據
        List<User> dbList2 = userService.getAll();
        System.out.println("第二次全量查詢結果:" + dbList2.toString());
    }
}

單元測試,運行后的輸出結果:

第一次全量查詢結果:[User{id=1, name='張三', age=20}, User{id=2, name='李四', age=21}, User{id=3, name='王五', age=22}]
查詢[id=2]結果:User{id=2, name='趙六', age=21}
第二次全量查詢結果:[User{id=1, name='張三', age=20}]

此時操作數據庫中的表數據,已經正常流通了。

上面介紹的JdbcTemplate只是最基本的幾個操作,更多其他數據訪問操作的使用可以參考:JdbcTemplate API

2.2、Thymeleaf 模板

在傳統的 Java web 工程中,通常會采用 JSP 來編寫頁面并進行數據展示。而在 Spring Boot 框架中,推薦使用 Thymeleaf 模板引擎來開發 Web 頁面。

Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 內容的模板引擎,與 JSP、Velocity、FreeMarker 等類似,都可以輕易的與 Spring MVC 等 Web 框架進行集成作為 Web 應用的模板引擎。

下面我們一起來看下簡單的頁面集成應用。

2.2.1、添加相關依賴包

在 SpringBoot 項目中使用 Thymeleaf 時,只需要添加所需的模板引擎模塊依賴包即可,內容如下。

<!--thymeleaf模板引擎-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2.2.2、添加相關的配置參數

與此同時,還需要在application.properties文件中配置 thymeleaf 模版掃描路徑,比如如下配置。

# thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true

其中spring.thymeleaf.prefix就是模板引擎掃描的路徑。

2.2.3、創建頁面模板

根據上一步映射的模板路徑, 在模板路徑src/main/resources/templates下新建模板文件index.html,內容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home Page</title>
</head>
<body>
<h1>Hello !</h1>
<table>
    <thead>
    <tr>
        <th>用戶ID</td>
        <th>用戶名稱</td>
        <th>用戶年齡</td>
    </tr>
    </thead>
    <tbody>
    <tr th:each="prod:${allUsers}">
        <td th:text="${prod.id}">100</td>
        <td th:text="${prod.name}">張三豐</td>
        <td th:text="${prod.age}">99</td>
    </tr>
    </tbody>
</table>
</body>
</html>

2.2.4、編寫頁面請求對象

最后編寫一個頁面請求對象,用來處理路徑的請求,將數據渲染到index頁面上,具體實現如下:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/")
    public String index(ModelMap map) {
        // 查詢所有的用戶
        List<User> users =  userService.getAll();
        map.addAttribute("allUsers", users);
        return "index";
    }
}

將上文中的三條數據插入到數據庫,以便展示。

2.2.5、測試頁面展示情況

最后將服務啟動,在瀏覽器發起請求,地址為http://localhost:8080/,展示結果如下:

圖片圖片

說明頁面渲染正常,符合預期效果。

更多 Thymeleaf 的頁面語法,可以訪問 Thymeleaf 的官方文檔來深入學習使用。

2.3、web 基本特性

除了以上功能,SpringBoot 還有幾個常用特性功能,比如 SpringMVC 中的接口開發、過濾器、攔截器、aop 代理、異常處理等。

下面,我們一起簡要的看看相關特性的用法。

2.3.1、接口開發

當與其它項目對接的時候,通常會采用 json 數據格式進行請求和返回,在傳統的 SpringMVC 項目中,我們通常需要在每個接口方法上加@ResponseBody注解,以便數據以 json 格式返回給用戶。

在 Spring Boot 框架中,我們只需要在接口類上添加@RestController注解,即可實現@Controller和@ResponseBody一樣的效果。

示例如下。

@RestController
public class ApiController {

    @Autowired
    private UserService userService;

    @GetMapping("/getUsers")
    public List<User> getUsers() {
        // 查詢所有的用戶
        System.out.println("收到查詢用戶的請求");
        List<User> users =  userService.getAll();
        return users;
    }
}

將服務啟動,訪問http://localhost:8080/getUsers,看看控制臺輸出結果。

圖片圖片

可以看到,與預期一致。

如果是頁面開發,只要使用@Controller注解即可,以免無法渲染數據。

2.3.2、過濾器

過濾器在 web 項目開發過程中經常會用到,比如用于收集調用日志、排除有 XSS 威脅的字符等,過濾器本質不屬于 SpringBoot 自帶的功能,而是 Servlet 提供的功能,SpringBoot 對此做了集成管理,實現方式也很簡單。

首先創建一個過濾器實現類,示例如下。

public class LogFilter implements Filter {


    @Override
    public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        System.out.println("日志過濾器,request url :"+request.getRequestURI());
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

然后將過濾器注冊到 SpringBoot 中,示例如下。

@Configuration
public class FilterConfig {

    /**
     * 添加過濾器
     * @return
     */
    @Bean
    public FilterRegistrationBean helloFilterRegistrationBean() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setName("logFilter"); // 指定過濾器名稱
        registration.setFilter(new LogFilter()); // 指定過濾器實現類
        registration.setUrlPatterns(Collections.singleton("/*"));// 指定攔截路徑
        registration.addInitParameter("paramName", "paramValue");// 指定初始化參數
        registration.setOrder(1);// 指定順序
        return registration;
    }
}

將服務啟動,訪問http://localhost:8080/getUsers,看看控制臺輸出結果。

日志過濾器,request url :/getUsers
收到查詢用戶的請求

說明過濾器已經正常工作了。

2.3.3、攔截器

攔截器在 web 項目開發過程中也經常會用到,比如用于用戶權限的攔截等等。攔截器屬于 SpringMVC 自帶的功能,因此 SpringBoot 默認就支持,實現方式也很簡單。

首先創建一個攔截器實現類,示例如下。

public class SignInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("方法前攔截,request url:" +  request.getRequestURI());
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("方法中攔截(不能攔截異常),request url:" +  request.getRequestURI());
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("方法后攔截(能攔截異常),request url:" +  request.getRequestURI());
    }
}

然后,將攔截器注冊到攔截器鏈中。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 將SignInterceptor添加到攔截器鏈中,并且指定攔截路徑和攔截順序
        registry.addInterceptor(new SignInterceptor()).addPathPatterns("/*").order(1);
    }
}

將服務啟動,訪問http://localhost:8080/getUsers,看看控制臺輸出結果。

方法前攔截,request url:/getUsers
收到查詢用戶的請求
方法中攔截(不能攔截異常),request url:/getUsers
方法后攔截(能攔截異常),request url:/getUsers

可以發現,過濾器的執行順序在攔截器之前。

其中攔截器中postHandle()和afterCompletion()方法,都可以實現對接口執行后進行攔截,兩者不同點在于:

  • postHandle()方法無法攔截異常;
  • afterCompletion()方法可以攔截異常;

可以新增一個getUsersError()方法,增加運行時異常。

@GetMapping("/getUsersError")
public List<User> getUsersError() {
    // 查詢所有的用戶
    System.out.println("收到查詢用戶的請求");
    if(1==1){
        throw new NullPointerException("異常測試");
    }
    List<User> users =  userService.getAll();
    return users;
}

再次請求訪問http://localhost:8080/getUsersError,控制臺輸出結果如下。

方法前攔截,request url:/getUsersError
收到查詢用戶的請求
方法后攔截,request url:/getUsersError

當出現異常時,可見postHandle()方法,沒有被執行。

2.3.4、aop 代理

aop 動態代理也是 web 項目開發過程中常用的功能特性,熟悉 Spring 的同學可能知道,Spring 的動態代理技術使用了 aspectj 框架的注解來實現切面技術,因此在使用的時候,需要添加相關的依賴包。

首先在pom.xml文件中添加 aspectj 依賴包,示例如下。

<!--添加 aspectj 依賴包 -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

編寫動態代理類,代理com.example.springboot.web包下所有類的public方法。

@Order(1)
@Component
@Aspect
public class ControllerAspect {

    /***
     * 定義切入點
     */
    @Pointcut("execution(public * com.example.springboot.web..*.*(..))")
    public void methodAdvice(){}

    /**
     * 方法調用前通知
     */
    @Before(value = "methodAdvice()")
    public void before(JoinPoint joinPoint){
        System.out.println("代理-> 來自Before通知,方法名稱:" +  joinPoint.getSignature().getName());
    }

    /**
     * 方法調用后通知
     */
    @After(value = "methodAdvice()")
    public void after(JoinPoint joinPoint){
        System.out.println("代理-> 來自After通知,方法名稱:" +  joinPoint.getSignature().getName());
    }

    /**
     * 方法調用后通知,方法正常執行后,有返回值,會通知;如果拋異常,不會通知
     */
    @AfterReturning(value = "methodAdvice()", returning = "returnVal")
    public void afterReturning(JoinPoint joinPoint,Object returnVal){
        System.out.println("代理-> 來自AfterReturning通知,方法名稱:" +  joinPoint.getSignature().getName() + ",返回值:" + returnVal.toString());
    }

    /**
     * 方法環繞通知
     */
    @Around(value = "methodAdvice()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("代理-> 來自Around環繞前置通知,方法名稱:" +  joinPoint.getSignature().getName());
        Object returnValue = joinPoint.proceed();
        System.out.println("代理-> 來自Around環繞后置通知,方法名稱:" +  joinPoint.getSignature().getName());
        return returnValue;
    }


    /**
     * 拋出異常通知
     */
    @AfterThrowing(value = "methodAdvice()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Exception ex) {
        System.out.println("代理-> 來自AfterThrowing通知,方法名稱:" +  joinPoint.getSignature().getName() + ",錯誤信息:"   + ex.getMessage());
    }
}

將服務啟動,訪問http://localhost:8080/getUsers,控制臺輸出結果如下。

代理-> 來自Around環繞前置通知,方法名稱:getUsers
代理-> 來自Before通知,方法名稱:getUsers
收到查詢用戶的請求
代理-> 來自Around環繞后置通知,方法名稱:getUsers
代理-> 來自After通知,方法名稱:getUsers
代理-> 來自AfterReturning通知,方法名稱:getUsers,返回值:[User{id=1, name='張三', age=20}, User{id=2, name='李四', age=21}, User{id=3, name='王五', age=22}]

訪問http://localhost:8080/getUsersError,控制臺輸出結果如下。

代理-> 來自Around環繞前置通知,方法名稱:getUsersError
代理-> 來自Before通知,方法名稱:getUsersError
收到查詢用戶的請求
代理-> 來自After通知,方法名稱:getUsersError
代理-> 來自AfterThrowing通知,方法名稱:getUsersError,錯誤信息:異常測試

可以很清晰的看到,當出現異常時AfterReturning()通知方法和Around環繞后置通知方法都不會執行,異常信息會進入到AfterThrowing() 通知方法中。

2.3.5、異常處理

Spring Boot 對異常處理也做了很多的支持,開發者可以通過@ExceptionHandler注解來全局代理異常信息,實現方式也很簡單。

編寫一個全局異常處理類,示例如下。

@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 處理Exception異常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Map exceptionHandler(Exception ex){
        Map<String,Object> errorMap = new HashMap<>();
        errorMap.put("code","500");
        errorMap.put("message",ex.getMessage());
        return errorMap;
    }
}

將服務啟動,訪問http://localhost:8080/getUsersError,控制臺輸出結果如下。

可以看到,異常請求被成功接管。

03、參考

1、https://springdoc.cn/spring-boot/index.html

責任編輯:武曉燕 來源: 潘志的研發筆記
相關推薦

2011-03-08 16:50:35

2020-09-04 15:38:19

Web前端開發項目

2021-03-02 06:32:03

Ansible系統運維

2019-11-13 15:44:17

Kafka架構數據

2025-02-28 08:42:53

SpringNetflixHystrix

2020-11-25 19:05:50

云計算SaaS公有云

2021-03-15 08:18:10

Web安全黑客漏洞

2021-12-06 09:00:00

開發WebDjango

2015-03-11 09:55:08

Web開發初學指南Web開發指南

2023-06-27 08:34:32

2023-02-08 16:20:39

2020-05-11 09:54:33

JavaScript開發技術

2013-04-10 15:14:18

Web App開發WebApp

2021-03-01 13:00:21

Ansible系統運維

2022-03-15 08:00:00

Flutter開發工具

2011-06-08 13:08:03

WEB設計

2022-11-04 14:58:59

應用開發鴻蒙

2021-07-28 06:51:08

FlaskPythonWeb

2010-12-23 13:45:23

Office 2010批量激活

2020-11-13 05:49:09

物聯網城域網IOT
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 羞羞网站免费 | 激情影院久久 | 国产精品中文字幕在线 | 97在线超碰 | 精品免费国产视频 | www成人啪啪18| 亚洲天堂成人在线视频 | 日韩在线视频免费观看 | 日韩成人精品 | 天色综合网 | 欧美国产精品一区二区 | 高清av在线| 欧美成人第一页 | 久久精品国产免费一区二区三区 | 热久久久 | 日韩av在线播 | 一区二区三区精品视频 | 国产三级| 亚洲精品乱码久久久久久蜜桃91 | av先锋资源 | 97成人免费| 国产小视频自拍 | 欧美一级欧美一级在线播放 | 国产精品久久久久久中文字 | av日韩一区| 欧洲国产精品视频 | 日韩一区二区三区四区五区六区 | 日韩av一区二区在线 | 羞羞视频免费在线 | 亚洲成人在线免费 | 欧美在线a | 日韩精品久久久久久 | 国产在线中文 | 中国黄色在线视频 | 91精品国产综合久久国产大片 | 亚洲视频精品 | 国产农村一级片 | 亚洲视频1区 | 日韩在线小视频 | 欧美xxxx网站 | 亚洲欧美日韩国产综合 |