Skip to content

Commit a23e136

Browse files
committed
completed regiest. remain rest api and exception
1 parent dd26653 commit a23e136

File tree

8 files changed

+118
-123
lines changed

8 files changed

+118
-123
lines changed

docs/blog-prototype.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
* q : 搜索关键字
2929
* /keywords : 最热搜索关键字列表
3030
* login : 登录
31-
* /login :POST
31+
* /login :GET 获取登录的界面
32+
* /login :POST 登录
3233
* register :注册
33-
* /register :POST
34+
* /register :GET 获取注册的界面
35+
* /register :POST 注册 , 注册成功跳转至 登录界面
3436
* users : 用户管理
3537
* /users : 用户列表
3638
* /users/{id} :具体某个用户的主页

docs/blog-user.md

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,72 @@
1-
# 博客系统的用户管理实现
2-
3-
4-
`security-in-action`项目基础上,我们构建了一个新的项目`blog-user`。项目的包名也做了调整,改为`com.waylau.spring.boot.blog`
5-
6-
## 实现功能
7-
8-
* 新增、删除、编辑用户
9-
* 分页查询;
10-
* 批量删除;
11-
* 用户名模糊搜索;
12-
13-
14-
## 环境
15-
16-
* Font-Awesome 4.7.0
17-
18-
## build.gradle
19-
20-
修改 build.gradle 文件,让我们的`blog-user`项目成为一个新的项目。
21-
22-
修改内容也比较简单,修改项目名称及版本即可。
23-
24-
```groovy
25-
jar {
26-
baseName = 'blog-user'
27-
version = '1.0.0'
28-
}
29-
```
30-
31-
32-
为了方便进行单元测试,我们添加了内嵌的 H2 数据库,并设置该库的范围类型为运行时(runtime):
33-
34-
35-
```groovy
36-
// 依赖关系
37-
dependencies {
38-
......
39-
// 添加 H2 的依赖
40-
runtime('com.h2database:h2:1.4.193')
41-
......
42-
}
43-
```
44-
45-
46-
## 问题解决
47-
48-
### 问题1
49-
50-
```
51-
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoconfigureTestDatabase.
52-
```
53-
54-
在测试类上,添加 `@AutoconfigureTestDatabase`
55-
56-
57-
### 问题2:Thymeleaf 取值 `${page.isLast}`报错
58-
59-
60-
61-
```
62-
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "page.isLast" (template: "fragments/page" - line 28, col 53)
63-
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393) ~[attoparser-2.0.2.RELEASE.jar:2.0.2.RELEASE]
64-
at org.attoparser.MarkupParser.parse(MarkupParser.java:257) ~[attoparser-2.0.2.RELEASE.jar:2.0.2.RELEASE]
65-
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230) ~[thymeleaf-3.0.3.RELEASE.jar:3.0.3.RELEASE]
66-
... 87 common frames omitted
67-
```
68-
69-
返回的 org.springframework.data.domain.Page 对象里面找不到 isLast 属性。
70-
1+
# 博客系统的用户管理实现
2+
3+
4+
`security-in-action`项目基础上,我们构建了一个新的项目`blog-user`。项目的包名也做了调整,改为`com.waylau.spring.boot.blog`
5+
6+
## 实现功能
7+
8+
* 新增、删除、编辑用户
9+
* 分页查询;
10+
* 批量删除;
11+
* 用户名模糊搜索;
12+
* 注册
13+
14+
15+
## 环境
16+
17+
* Font-Awesome 4.7.0
18+
19+
## build.gradle
20+
21+
修改 build.gradle 文件,让我们的`blog-user`项目成为一个新的项目。
22+
23+
修改内容也比较简单,修改项目名称及版本即可。
24+
25+
```groovy
26+
jar {
27+
baseName = 'blog-user'
28+
version = '1.0.0'
29+
}
30+
```
31+
32+
33+
为了方便进行单元测试,我们添加了内嵌的 H2 数据库,并设置该库的范围类型为运行时(runtime):
34+
35+
36+
```groovy
37+
// 依赖关系
38+
dependencies {
39+
......
40+
// 添加 H2 的依赖
41+
runtime('com.h2database:h2:1.4.193')
42+
......
43+
}
44+
```
45+
46+
47+
## 问题解决
48+
49+
### 问题1
50+
51+
```
52+
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoconfigureTestDatabase.
53+
```
54+
55+
在测试类上,添加 `@AutoconfigureTestDatabase`
56+
57+
58+
### 问题2:Thymeleaf 取值 `${page.isLast}`报错
59+
60+
61+
62+
```
63+
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "page.isLast" (template: "fragments/page" - line 28, col 53)
64+
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393) ~[attoparser-2.0.2.RELEASE.jar:2.0.2.RELEASE]
65+
at org.attoparser.MarkupParser.parse(MarkupParser.java:257) ~[attoparser-2.0.2.RELEASE.jar:2.0.2.RELEASE]
66+
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230) ~[thymeleaf-3.0.3.RELEASE.jar:3.0.3.RELEASE]
67+
... 87 common frames omitted
68+
```
69+
70+
返回的 org.springframework.data.domain.Page 对象里面找不到 isLast 属性。
71+
7172
解决: 这个是序列化转化的问题。布尔值 isLast 映射为属性是 last,所以改为 `${page.last}`即可。

samples/blog-user/src/main/java/com/waylau/spring/boot/blog/controller/MainController.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
package com.waylau.spring.boot.blog.controller;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
37
import org.springframework.stereotype.Controller;
48
import org.springframework.ui.Model;
59
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.PostMapping;
11+
12+
import com.waylau.spring.boot.blog.domain.Authority;
13+
import com.waylau.spring.boot.blog.domain.User;
14+
import com.waylau.spring.boot.blog.service.AuthorityService;
15+
import com.waylau.spring.boot.blog.service.UserService;
616

717
/**
818
* 主页控制器.
@@ -13,6 +23,14 @@
1323
@Controller
1424
public class MainController {
1525

26+
private static final Long ROLE_USER_AUTHORITY_ID = 2L;
27+
28+
@Autowired
29+
private UserService userService;
30+
31+
@Autowired
32+
private AuthorityService authorityService;
33+
1634
@GetMapping("/")
1735
public String root() {
1836
return "redirect:/index";
@@ -44,6 +62,22 @@ public String register() {
4462
return "register";
4563
}
4664

65+
/**
66+
* 注册用户
67+
* @param user
68+
* @param result
69+
* @param redirect
70+
* @return
71+
*/
72+
@PostMapping("/register")
73+
public String registerUser(User user) {
74+
List<Authority> authorities = new ArrayList<>();
75+
authorities.add(authorityService.getAuthorityById(ROLE_USER_AUTHORITY_ID));
76+
user.setAuthorities(authorities);
77+
userService.saveUser(user);
78+
return "redirect:/login";
79+
}
80+
4781
@GetMapping("/search")
4882
public String search() {
4983
return "search";

samples/blog-user/src/main/java/com/waylau/spring/boot/blog/controller/UserController.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public ResponseEntity<User> create(User user, Long authorityId) {
9696
* @return
9797
*/
9898
@DeleteMapping(value = "/{id}")
99-
@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
10099
public ResponseEntity<String> delete(@PathVariable("id") Long id, Model model) {
101100
userService.removeUser(id);
102101
return ResponseEntity.ok().body( "删除成功!");

samples/blog-user/src/main/java/com/waylau/spring/boot/blog/service/AuthorityService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public interface AuthorityService {
1313

1414
/**
1515
* 根据id获取 Authority
16-
* @param user
16+
* @param Authority
1717
* @return
1818
*/
1919
Authority getAuthorityById(Long id);

samples/blog-user/src/main/resources/static/js/users/main.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ $(function() {
1212

1313
var _pageSize; // 存储用于搜索
1414

15-
// 获取 CSRF Token
16-
var csrfHeader = $("meta[name='_csrf']").attr("content");
17-
var csrfToken = $("meta[name='_csrf_header']").attr("content");
18-
1915
// 根据用户名、页面索引、页面大小获取用户列表
2016
function getUersByName(pageIndex, pageSize) {
2117
$.ajax({
@@ -93,6 +89,12 @@ $(function() {
9389

9490
// 删除用户
9591
$(".blog-delete-user").click(function() {
92+
93+
// 获取 CSRF Token
94+
var csrfToken = $("meta[name='_csrf']").attr("content");
95+
var csrfHeader = $("meta[name='_csrf_header']").attr("content");
96+
97+
9698
$.ajax({
9799
url: "/users/" + $(this).attr("userId") ,
98100
type: 'DELETE',

samples/blog-user/src/main/resources/templates/admins/index.html

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,49 +34,7 @@ <h5 class="card-header"><i class="fa fa-bars" aria-hidden="true"></i> 菜单</h5
3434

3535
<div class="col-md-8 col-xl-9">
3636
<div class="card" id="rightContainer">
37-
<div class="card-header bg-dark font-white">
38-
<i class="fa fa-sidebar fa-star-o " aria-hidden="true"></i> Users Overview
39-
</div>
40-
<div class="container">
41-
<div class="row">
42-
<table class="table table-striped">
43-
<thead>
44-
<tr>
45-
<th>#</th>
46-
<th>Username</th>
47-
<th>Full Name</th>
48-
<th>Role</th>
49-
<th>Created At</th>
50-
</tr>
51-
</thead>
52-
<tbody>
53-
<tr>
54-
<th scope="row">1</th>
55-
<td>Mark</td>
56-
<td>Otto</td>
57-
<td>@mdo</td>
58-
<td>@mdo</td>
59-
</tr>
60-
<tr>
61-
<th scope="row">2</th>
62-
<td>Jacob</td>
63-
<td>Thornton</td>
64-
<td>@fat</td>
65-
<td>@mdo</td>
66-
</tr>
67-
<tr>
68-
<th scope="row">3</th>
69-
<td>Larry</td>
70-
<td>the Bird</td>
71-
<td>@twitter</td>
72-
<td>@mdo</td>
73-
</tr>
74-
</tbody>
75-
</table>
76-
</div>
77-
</div>
78-
</div>
79-
37+
</div>
8038
</div>
8139
</div>
8240
<!-- /.row -->

samples/blog-user/src/main/resources/templates/register.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<div class="container blog-content-container">
99

10-
<form >
10+
<form th:action="@{/register}" method="post">
1111
<h2 class="form-signin-heading">注册成为博主</h2>
1212

1313
<div class="form-group col-md-5">
@@ -31,7 +31,6 @@ <h2 class="form-signin-heading">注册成为博主</h2>
3131
<button type="submit" class="btn btn-primary">提交</button>
3232
</div>
3333
</form>
34-
3534
</div> <!-- /container -->
3635

3736

0 commit comments

Comments
 (0)