偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

SpringBoot 開發(fā) Web 系統(tǒng),快速入門指南!

開發(fā) 前端
在傳統(tǒng)的 Java web 工程中,通常會(huì)采用 JSP 來編寫頁面并進(jìn)行數(shù)據(jù)展示。而在 Spring Boot 框架中,推薦使用 Thymeleaf 模板引擎來開發(fā) Web 頁面。

01、背景介紹

在之前的文章中,我們簡(jiǎn)單的介紹了 SpringBoot 項(xiàng)目的創(chuàng)建過程,了解了 Spring Boot 開箱即用的特性,本篇文章接著上篇的內(nèi)容繼續(xù)介紹 Spring Boot 用于 web 工程開發(fā)時(shí)的其它特性。

廢話不多說了,上代碼!

02、應(yīng)用實(shí)踐

當(dāng)將 SpringBoot 框架用于傳統(tǒng)的 web 項(xiàng)目開發(fā)時(shí),通常分為以下三個(gè)過程來實(shí)現(xiàn)。

  • 第一步:連接數(shù)據(jù)庫,實(shí)現(xiàn)對(duì)表進(jìn)行 CRUD 操作
  • 第二步:引入模板引擎來開發(fā)頁面
  • 第三步:使用一些常見的 web 特性來滿足其它的功能開發(fā)

最后源碼目錄結(jié)構(gòu)如下!

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

下面我們依次來看看相關(guān)的實(shí)踐過程。

2.1、數(shù)據(jù)庫操作

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

2.1.1、準(zhǔn)備數(shù)據(jù)庫表

先創(chuàng)建tb_user表,包含屬性id、name、age,可以通過執(zhí)行下面的建表語句。

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、添加相關(guān)依賴包

在我們?cè)L問數(shù)據(jù)庫的時(shí)候,需要先配置一個(gè)數(shù)據(jù)庫驅(qū)動(dòng)包,通常采用 JDBC 方式方式訪問,需要在pom.xml中引入相關(guān)依賴包。

<!--spring jdbc-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mysql 驅(qū)動(dòng)-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2.1.3、添加數(shù)據(jù)源配置

與此同時(shí),還需要在application.properties文件中配置相關(guān)的數(shù)據(jù)源訪問地址。

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、編寫領(lǐng)域?qū)ο?/h4>

根據(jù)數(shù)據(jù)庫中創(chuàng)建的 User 表,創(chuàng)建對(duì)應(yīng)的領(lǐng)域?qū)ο蟆?/p>

package com.example.springboot.entity;

public class User {

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

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

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

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

2.1.5、編寫數(shù)據(jù)訪問對(duì)象

通過JdbcTemplate實(shí)現(xiàn)對(duì)tb_user表中的數(shù)據(jù)訪問操作。

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;
    }

    /**
     * 創(chuàng)建用戶
     * @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、編寫單元測(cè)試用例

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

package com.example.springboot;

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

    @Autowired
    private UserService userService;

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

        // 查詢?nèi)繑?shù)據(jù)
        List<User> dbList1 = userService.getAll();
        System.out.println("第一次全量查詢結(jié)果:" + dbList1.toString());

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

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

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

        // 查詢?nèi)繑?shù)據(jù)
        List<User> dbList2 = userService.getAll();
        System.out.println("第二次全量查詢結(jié)果:" + dbList2.toString());
    }
}

單元測(cè)試,運(yùn)行后的輸出結(jié)果:

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

此時(shí)操作數(shù)據(jù)庫中的表數(shù)據(jù),已經(jīng)正常流通了。

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

2.2、Thymeleaf 模板

在傳統(tǒng)的 Java web 工程中,通常會(huì)采用 JSP 來編寫頁面并進(jìn)行數(shù)據(jù)展示。而在 Spring Boot 框架中,推薦使用 Thymeleaf 模板引擎來開發(fā) Web 頁面。

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

下面我們一起來看下簡(jiǎn)單的頁面集成應(yīng)用。

2.2.1、添加相關(guān)依賴包

在 SpringBoot 項(xiàng)目中使用 Thymeleaf 時(shí),只需要添加所需的模板引擎模塊依賴包即可,內(nèi)容如下。

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

2.2.2、添加相關(guān)的配置參數(shù)

與此同時(shí),還需要在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、創(chuàng)建頁面模板

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

<!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、編寫頁面請(qǐng)求對(duì)象

最后編寫一個(gè)頁面請(qǐng)求對(duì)象,用來處理路徑的請(qǐng)求,將數(shù)據(jù)渲染到index頁面上,具體實(shí)現(xiàn)如下:

@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";
    }
}

將上文中的三條數(shù)據(jù)插入到數(shù)據(jù)庫,以便展示。

2.2.5、測(cè)試頁面展示情況

最后將服務(wù)啟動(dòng),在瀏覽器發(fā)起請(qǐng)求,地址為http://localhost:8080/,展示結(jié)果如下:

圖片圖片

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

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

2.3、web 基本特性

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

下面,我們一起簡(jiǎn)要的看看相關(guān)特性的用法。

2.3.1、接口開發(fā)

當(dāng)與其它項(xiàng)目對(duì)接的時(shí)候,通常會(huì)采用 json 數(shù)據(jù)格式進(jìn)行請(qǐng)求和返回,在傳統(tǒng)的 SpringMVC 項(xiàng)目中,我們通常需要在每個(gè)接口方法上加@ResponseBody注解,以便數(shù)據(jù)以 json 格式返回給用戶。

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

示例如下。

@RestController
public class ApiController {

    @Autowired
    private UserService userService;

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

將服務(wù)啟動(dòng),訪問http://localhost:8080/getUsers,看看控制臺(tái)輸出結(jié)果。

圖片圖片

可以看到,與預(yù)期一致。

如果是頁面開發(fā),只要使用@Controller注解即可,以免無法渲染數(shù)據(jù)。

2.3.2、過濾器

過濾器在 web 項(xiàng)目開發(fā)過程中經(jīng)常會(huì)用到,比如用于收集調(diào)用日志、排除有 XSS 威脅的字符等,過濾器本質(zhì)不屬于 SpringBoot 自帶的功能,而是 Servlet 提供的功能,SpringBoot 對(duì)此做了集成管理,實(shí)現(xiàn)方式也很簡(jiǎn)單。

首先創(chuàng)建一個(gè)過濾器實(shí)現(xiàn)類,示例如下。

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() {

    }
}

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

@Configuration
public class FilterConfig {

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

將服務(wù)啟動(dòng),訪問http://localhost:8080/getUsers,看看控制臺(tái)輸出結(jié)果。

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

說明過濾器已經(jīng)正常工作了。

2.3.3、攔截器

攔截器在 web 項(xiàng)目開發(fā)過程中也經(jīng)常會(huì)用到,比如用于用戶權(quán)限的攔截等等。攔截器屬于 SpringMVC 自帶的功能,因此 SpringBoot 默認(rèn)就支持,實(shí)現(xiàn)方式也很簡(jiǎn)單。

首先創(chuàng)建一個(gè)攔截器實(shí)現(xiàn)類,示例如下。

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());
    }
}

然后,將攔截器注冊(cè)到攔截器鏈中。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

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

將服務(wù)啟動(dòng),訪問http://localhost:8080/getUsers,看看控制臺(tái)輸出結(jié)果。

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

可以發(fā)現(xiàn),過濾器的執(zhí)行順序在攔截器之前。

其中攔截器中postHandle()和afterCompletion()方法,都可以實(shí)現(xiàn)對(duì)接口執(zhí)行后進(jìn)行攔截,兩者不同點(diǎn)在于:

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

可以新增一個(gè)getUsersError()方法,增加運(yùn)行時(shí)異常。

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

再次請(qǐng)求訪問http://localhost:8080/getUsersError,控制臺(tái)輸出結(jié)果如下。

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

當(dāng)出現(xiàn)異常時(shí),可見postHandle()方法,沒有被執(zhí)行。

2.3.4、aop 代理

aop 動(dòng)態(tài)代理也是 web 項(xiàng)目開發(fā)過程中常用的功能特性,熟悉 Spring 的同學(xué)可能知道,Spring 的動(dòng)態(tài)代理技術(shù)使用了 aspectj 框架的注解來實(shí)現(xiàn)切面技術(shù),因此在使用的時(shí)候,需要添加相關(guān)的依賴包。

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

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

編寫動(dòng)態(tài)代理類,代理com.example.springboot.web包下所有類的public方法。

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

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

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

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

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

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


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

將服務(wù)啟動(dòng),訪問http://localhost:8080/getUsers,控制臺(tái)輸出結(jié)果如下。

代理-> 來自Around環(huán)繞前置通知,方法名稱:getUsers
代理-> 來自Before通知,方法名稱:getUsers
收到查詢用戶的請(qǐng)求
代理-> 來自Around環(huán)繞后置通知,方法名稱: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,控制臺(tái)輸出結(jié)果如下。

代理-> 來自Around環(huán)繞前置通知,方法名稱:getUsersError
代理-> 來自Before通知,方法名稱:getUsersError
收到查詢用戶的請(qǐng)求
代理-> 來自After通知,方法名稱:getUsersError
代理-> 來自AfterThrowing通知,方法名稱:getUsersError,錯(cuò)誤信息:異常測(cè)試

可以很清晰的看到,當(dāng)出現(xiàn)異常時(shí)AfterReturning()通知方法和Around環(huán)繞后置通知方法都不會(huì)執(zhí)行,異常信息會(huì)進(jìn)入到AfterThrowing() 通知方法中。

2.3.5、異常處理

Spring Boot 對(duì)異常處理也做了很多的支持,開發(fā)者可以通過@ExceptionHandler注解來全局代理異常信息,實(shí)現(xiàn)方式也很簡(jiǎn)單。

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

@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;
    }
}

將服務(wù)啟動(dòng),訪問http://localhost:8080/getUsersError,控制臺(tái)輸出結(jié)果如下。

可以看到,異常請(qǐng)求被成功接管。

03、參考

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

責(zé)任編輯:武曉燕 來源: 潘志的研發(fā)筆記
相關(guān)推薦

2011-03-08 16:50:35

2020-09-04 15:38:19

Web前端開發(fā)項(xiàng)目

2021-03-02 06:32:03

Ansible系統(tǒng)運(yùn)維

2019-11-13 15:44:17

Kafka架構(gòu)數(shù)據(jù)

2025-02-28 08:42:53

SpringNetflixHystrix

2020-11-25 19:05:50

云計(jì)算SaaS公有云

2021-12-06 09:00:00

開發(fā)WebDjango

2021-03-15 08:18:10

Web安全黑客漏洞

2015-03-11 09:55:08

Web開發(fā)初學(xué)指南Web開發(fā)指南

2023-06-27 08:34:32

2013-04-10 15:14:18

Web App開發(fā)WebApp

2023-02-08 16:20:39

2020-05-11 09:54:33

JavaScript開發(fā)技術(shù)

2021-03-01 13:00:21

Ansible系統(tǒng)運(yùn)維

2022-11-04 14:58:59

應(yīng)用開發(fā)鴻蒙

2022-03-15 08:00:00

Flutter開發(fā)工具

2021-07-28 06:51:08

FlaskPythonWeb

2011-06-08 13:08:03

WEB設(shè)計(jì)

2010-12-23 13:45:23

Office 2010批量激活

2020-11-13 05:49:09

物聯(lián)網(wǎng)城域網(wǎng)IOT
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)