Эта серия разделена на четыре части:
- Внутренний интерфейс четырех шагов создания веб-сайта (SpringBoot+ онлайн)
- Поисковый робот данных Python (selenium) четырех шагов создания веб-сайта
- Внешний вид четырех шагов создания веб-сайта (React + онлайн)
- Построение четырехсекционного механизма (Android + онлайн)
ноль, предисловие
Чтобы обобщить полученные знания, эта серия статей посвящена моему опыту 2018 года.
В этой статье основное внимание уделяется созданию внутренней службы интерфейса URL-адресов и запуску ее на сервере.
Технические моменты, кратко изложенные в этой статье:SpringBoot,mybaits整合,mysql简单操作,ResetFul接口,文件上传,跨域处理
Во-первых, первоначальная конструкция SpringBoot
1. Создайте новый проект SpringBoot в Idea (с субподрядом следующим образом):
Какую кнопку нажать, чтобы создать новый проект, здесь нет ерунды, перейдите по ссылке: [SpringBoot-01-Первый опыт](ву ву Краткое описание.com/fear/74 0 из 9573…
)
2. Добавьте зависимости в pom.xml:
<dependencies>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3. Настройте application.properties (или application.yml, мне больше нравится последний)
Обратите внимание на модификацию: имя базы данных
mycode,имя пользователя:username: XXXX,пароль:password: XXXX
spring:
datasource:
url: jdbc:mysql://localhost:3306/mycode?useSSL=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&URIEncoding="UTF-8"
username: root
password: ****
driver-class-name: com.mysql.jdbc.Driver
#坑点0 配置mybatis的xml位置
mybatis:
mapper-locations: classpath:mapper/*.xml
Две ямы, на которые наступил этот знак:
1).好像是MySQL时区的问题,导致连接异常:
>配置时数据库连接参数添加:`&serverTimezone=Asia/Shanghai`可解决
2).一开始用get测试是否插入成功,但是报错了,仔细看了看,貌似是从中文的地方:
>配置时数据库连接参数添加:`&URIEncoding="UTF-8"`
Во-вторых, краткое описание MySQL
1. Создайте базу данных и постройте таблицу
1). Определить желаемый мономер
{
"id":"1"
"type": "绘图相关",
"name": "Android关于Canvas你所知道的和不知道的一切",
"localPath":"I:\Java\Android\Unit\C\app\src\main\java\com\toly1994\c\view\CanvasView.java",
"jianshuUrl":"https://www.jianshu.com/p/4bc05f646bfe",
"juejinUrl":"https://juejin.cn/post/6844903705930629128",
"imgUrl":"域名:端口/android/Android关于Canvas你所知道的和不知道的一切.png",
"createTime":"2018-11-05"
}
2) Создать базу данныхmycodeи столandroid
//创建数据库
CREATE DATABASE mycode;
USE mycode;
//创建表
CREATE TABLE android (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(8) NOT NULL,
name VARCHAR(32) NOT NULL,
localPath VARCHAR(120) NOT NULL,
jianshuUrl VARCHAR(120) NOT NULL,
juejinUrl VARCHAR(120) NOT NULL,
imgUrl VARCHAR(120) NOT NULL,
createTime DATE NOT NULL
);
3) Чтобы обобщить запрос на объединение, создайте таблицуtype
CREATE TABLE type(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type_idx VARCHAR(4) NOT NULL,
type VARCHAR(48) NOT NULL
);
4) Вставьте данные типа:
INSERT INTO type(type_idx, type)
VALUES('ABCS', '四大组件'), ('C', '绘图相关'), ('D', '自定义控件'),
('F', 'Fragment'), ('G', '开源计划'), ('V', '原生View'),
('MD', '材料设计'), ('L', '底层核心'), ('M', '多媒体相关'),
('N', '网络相关'), ('O', '三方框架'), ('P', '手机设备相关'),
('S', '数据存读相关'), ('T', '纷杂小技术');
2. Краткий обзор операторов MySQL
-->插入数据:
insert into android(type,name,localPath,jianshuUrl,juejinUrl,imgUrl,createTime)
values (XX,XX,XX,XX,XX,XX,XX)
-->更新数据:
UPDATE android
SET type=XX,name=XX,localPath=XX,jianshuUrl=XX,juejinUrl=XX,imgUrl=XX,createTime=XX
WHERE id=XX
-->查询所有+INNER JOIN
<select id="findALL" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx;
</select>
-->根据id查询
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE a.id=XX
-->根据type查询
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE a.type=XX;
-->根据name部分字符查询
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE name like '%XX%';
-->根据id删除数据
DELETE FROM android
WHERE id=#{id}
3. Процесс записи + тест на вставку:
1. Вводный файл
1.AndroidProjectApplication.java 启动文件,坑点在加扫包范围
2.application.yml 配置文件
3.Note.xml 通过sql语句操作数据库映射出实体类返给dao
4.NoteDao.java 数据库操作接口
5.NoteService.java 根据业务逻辑对dao返回的数据进行一定加工
6.Note.java 实体类,用于承接数据库中的数据
7.NoteController.java 核心操作层,生成可访问的url接口,向外暴露
Ниже приведена демонстрация процесса работы путем вставки данных
2. Создайте класс сущности:toly1994.com.android_project.bean.Note.java
public class Note {
private int id;//id
private String type;//类型
private String name;//名称
private String localPath;//路径
private String jianshuUrl;//简书地址
private String juejinUrl;//掘金地址
private String imgUrl;//掘金地址
private String createTime;//创建时间
//构造方法,get、set、toString略
}
3. Сопоставление xml:mapper/Note.xml
По спецификации достаточно написать sql-оператор в соответствующей позиции
в#{type}Представляет параметры, переданные методом в dao
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--坑点2:命名空间指向对应dao类名-->
<mapper namespace="toly1994.com.android_project.dao.NoteDao">
<!--坑点3:id为dao中相应方法名-->
<insert id="insert">
insert into android(type,name,localPath,jianshuUrl,juejinUrl,imgUrl,createTime)
values (#{type},#{name},#{localPath},#{jianshuUrl},#{juejinUrl},#{imgUrl},#{createTime})
</insert>
</mapper>
4. Работа с базой данных: toly1994.com.android_project.dao.NoteDao
/**
* 作者:张风捷特烈
* 时间:2018/11/19 0019:13:27
* 邮箱:1981462002@qq.com
* 说明:dao层---数据库操作
*/
public interface NoteDao {
//坑点1 java没有保存形参的记录,所以多参数用户@Param("name")起名字,不然无法识别
int insert(@Param("type") String type,
@Param("name") String name,
@Param("localPath") String localPath,
@Param("jianshuUrl") String jianshuUrl,
@Param("juejinUrl") String juejinUrl,
@Param("imgUrl") String imgUrl,
@Param("createTime") String createTime);
}
5. Бизнес-уровень: toly1994.com.android_project.service.NoteService
/**
* 作者:张风捷特烈
* 时间:2018/11/19 0019:13:48
* 邮箱:1981462002@qq.com
* 说明:Service层---操作dao
*/
@Service
public class NoteService {
@Autowired
private NoteDao mNoteDao;
@Transactional
public String insertNote(Note note) {
mNoteDao.insert(note.getType(), note.getName(),
note.getLocalPath(), note.getJianshuUrl(),
note.getJuejinUrl(), note.getImgUrl(),
note.getCreateTime());
return "OK";
}
}
6. Уровень управления: toly1994.com.android_project.controller.NoteController
/**
* 作者:张风捷特烈
* 时间:2018/11/19 0019:13:34
* 邮箱:1981462002@qq.com
* 说明:控制层---生成url接口
*/
@RestController
public class NoteController {
@Autowired
private NoteService mNoteService;
@GetMapping("/test/insert")
public String insert() {
Note note = new Note("C", "Android关于Canvas你所知道的和不知道的一切",
"I:\\Java\\Android\\Unit\\C\\app\\src\\main\\java\\com\\toly1994\\c\\view\\CanvasView.java"
, "https://www.jianshu.com/p/4bc05f646bfe", "https://juejin.cn/post/6844903705930629128",
"http://localhost:8080/android/Android关于Canvas你所知道的和不知道的一切.png", "null");
mNoteService.insertNote(note);
return "ok";
}
}
7. Класс запуска: обратите внимание на ямы, классы запуска и пакеты сканирования.
@SpringBootApplication
//坑点5:将dao添加扫包范围
@MapperScan(basePackages = {"toly1994.com.android_project.dao"})
public class AndroidProjectApplication {
public static void main(String[] args) {
SpringApplication.run(AndroidProjectApplication.class, args);
}
}
Вы можете вставить данные в базу данных, обратившись к интерфейсу в браузере: (здесь сначала используйте GET для проверки, а затем сделайте POST)
В-четвертых, реализовать API-интерфейс RESTFUL (простой CRUD)
1.POST добавить данные:http://域名:端口/api/android/note
Интерфейс принимает спокойный стиль равномерно: / API / Android / XXX,О стиле RESTFUL см.:
Измените контроллер: NoteController, измените метод вставки на POST и верните информацию о вставке (в формате json) посетителю после вставки.
/**
* 作者:张风捷特烈
* 时间:2018/11/19 0019:13:34
* 邮箱:1981462002@qq.com
* 说明:控制层---生成url接口
*/
@RestController
@RequestMapping(value = "/api/android")
public class NoteController {
@Autowired
private NoteService mNoteService;
@PostMapping(value = "/note")
public Note addOne(@ModelAttribute Note note) {
mNoteService.insertNote(note);
return note;
}
}
2.PUT для изменения данных:http://192.168.43.60:8089/api/android/note/[id]
1).mapper/Note.xml: добавить оператор SQL
<update id="updateById">
UPDATE android
SET type=#{type},name=#{name},localPath=#{localPath},jianshuUrl=#{jianshuUrl},juejinUrl=#{juejinUrl},imgUrl=#{imgUrl}
WHERE id=#{id}
</update>
2).NoteDao: Добавить интерфейс метода
/**
* 通过id修改一条记录
*
* @param id
* @return
*/
void updateById(@Param("id") int id,
@Param("type") String type,
@Param("name") String name,
@Param("localPath") String localPath,
@Param("jianshuUrl") String jianshuUrl,
@Param("juejinUrl") String juejinUrl,
@Param("imgUrl") String imgUrl,
@Param("createTime") String createTime);
3). NOCEVICE: добавить метод сервисного слоя
@Transactional
public Note updateNote(int id, Note note) {
mNoteDao.updateById(id,
note.getType(),
note.getName(),
note.getLocalPath(),
note.getJianshuUrl(),
note.getJuejinUrl(),
note.getImgUrl(),
note.getCreateTime());
return note;
}
4) .NoteController: добавить интерфейс доступа к URL
@PutMapping(value = "/note/{id}")
public Note updateById(@PathVariable("id") Integer id, @ModelAttribute Note note) {
mNoteService.updateNote(id,note);
return note;
}
3. Данные запроса:
После вышеизложенного вы должны быть знакомы с методом записи:
Сначала добавьте методы в dao, затем напишите SQL, а затем перенесите dao на контроллер с сервисом.
//DAO
/**
* 查询所有
* @return
*/
List<Note> findALL();
//SQL语句
<select id="findALL" resultType="toly1994.com.android_project.bean.Note">
SELECT*FROM android
</select>
//Service
public List<Note> findAll() {
return mNoteDao.findALL();
}
//Controller
@GetMapping(value = "/note")
public List<Note> findAll() {
return mNoteService.findAll();
}
4. Запрос один (в качестве примера возьмем поле id, остальные поля аналогичны)
//DAO
/**
* 根据id查询
* @return
*/
Note findById(@Param("id") int id);
//SQL语句
<select id="findById" resultType="toly1994.com.android_project.bean.Note">
SELECT*FROM android
WHERE id=#{id}
</select>
//Service
public Note findById(int id){
return mNoteDao.findById(id);
}
//Controller
@GetMapping(value = "/note/{id}")
public Note findById(@PathVariable("id") Integer id) {
return mNoteService.findById(id);
}
5. Удалить отдельные данные (в качестве примера возьмем поле id, остальные поля аналогичны)
//DAO
/**
* 根据id删除
* @param id
*/
void deleteById(@Param("id") int id);
//SQL语句
<delete id="deleteById">
DELETE FROM android
WHERE id=#{id}
</delete>
//Service
@Transactional
public int deleteById(int id){
mNoteDao.deleteById(id);
return id;
}
//Controller
@DeleteMapping(value = "/note/{id}")
public int deleteById(@PathVariable("id") Integer id) {
return mNoteService.deleteById(id);
}
3. Оптимизация и унификация формы возврата данных и захват исключений
1. Результат Единая форма возврата
//成功的json:
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 2,
"type": "B",
"name": "BASE",
"localPath": "c",
"jianshuUrl": "http://jianshu",
"juejinUrl": "http://juejin",
"imgUrl": "imgUrl",
"create": null
}
}
//失败的json:
{
"code": 500,
"msg": "/ by zero",
"data": null
}
2. Реализация единого формата:
/**
* 作者:张风捷特烈
* 时间:2018/5/25:15:30
* 邮箱:1981462002@qq.com
* 说明:格式化请求返回值
*/
public class ResultBean<T> {
private int code;
private String msg;
private T data;
public ResultBean(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
//get、set、toString省略
}
3. Используйте классы перечисления для унификации кодов ошибок и обслуживания информации об ошибках.
Он используется для поддержки некоторых списков ошибок, которые можно настраивать и выдавать при перехвате исключений для управления.
Например, запрос идентификатора, который не существует в базе данных, не будет сообщать об ошибке по умолчанию.В этом случае вы можете настроить исключение неизвестного идентификатора и зафиксировать его на уровне службы.
/**
* 作者:张风捷特烈
* 时间:2018/5/25:17:36
* 邮箱:1981462002@qq.com
* 说明:使用枚举类统一错误码与错误信息维护
*/
public enum ResultEnum {
SUCCESS(200, "操作成功"),
EXCEPTION(500, "起它异常"),
NOT_FOUND_ID(102, "未知id");
private int code;
private String msg;
ResultEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
/**
* 作者:张风捷特烈
* 时间:2018/5/25:17:14
* 邮箱:1981462002@qq.com
* 说明:id未知异常
*/
public class NotFoundIdException extends RuntimeException {
private int code;
private static String msg = ResultEnum.NOT_FOUND_ID.getMsg();
public NotFoundIdException() {
super(msg);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
//Service中捕获异常
public Note findById(int id) {
Note byId = mNoteDao.findById(id);
if (byId == null) {
throw new NotFoundIdException();
}
return byId;
}
4. Класс обработки результатов
Используйте этот класс для преобразования всех результатов в объекты ResultBean для достижения унификации возвращаемых значений.
/**
* 作者:张风捷特烈
* 时间:2018/5/30:18:37
* 邮箱:1981462002@qq.com
* 说明:结果处理类
*/
public class ResultHandler {
/**
* 成功时将object对象转化为ResultBean对象
*
* @param o
* @return
*/
public static ResultBean ok(Object o) {
return new ResultBean(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), o);
}
/**
* 使用枚举列举错误类型
*
* @param error
* @return
*/
public static ResultBean error(ResultEnum error) {
return new ResultBean(error.getCode(), error.getMsg(), null);
}
public static ResultBean error(String e) {
return new ResultBean(ResultEnum.EXCEPTION.getCode(), e, null);
}
}
5. Захват исключений:
@ExceptionHandler и @ControllerAdvice заставляют все исключения идти сюда, унифицированная обработка ResultHandler
Здесь вы можете настроить некоторые исключения для проекта
/**
* 异常捕获类
*/
@ControllerAdvice
public class ExceptionHandle {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResultBean handle(Exception e) {
return ResultHandler.error(e.getMessage());
}
}
6. Оберните все возвращенные результаты в контроллере в ResultBean
@RestController
@RequestMapping(value = "/api/android")
public class NoteController {
@Autowired
private NoteService mNoteService;
@PostMapping(value = "/note")
public ResultBean addOne(@ModelAttribute Note note) {
mNoteService.insertNote(note);
return ResultHandler.ok(note);
}
@PutMapping(value = "/note/{id}")
public ResultBean updateById(@PathVariable("id") Integer id, @ModelAttribute Note note) {
mNoteService.updateNote(id, note);
return ResultHandler.ok(note);
}
@GetMapping(value = "/note")
public ResultBean findAll() {
return ResultHandler.ok(mNoteService.findAll());
}
@GetMapping(value = "/note/{id}")
public ResultBean findById(@PathVariable("id") Integer id) {
return ResultHandler.ok(mNoteService.findById(id));
}
@DeleteMapping(value = "/note/{id}")
public ResultBean deleteById(@PathVariable("id") Integer id) {
return ResultHandler.ok(mNoteService.deleteById(id));
}
}
Пятое: оптимизация и дополнение
1. Резюме запроса
В общем интерфейсы такие: (имя доменаhttp://192.168.43.60, порт: 8089переделывай сам)
查询:GET请求
查询所有:http://192.168.43.60:8089/api/android/note
查询id=1: http://192.168.43.60:8089/api/android/note/1
查询type=C: http://192.168.43.60:8089/api/android/note/type/C
查询名字有View的:http://192.168.43.60:8089/api/android/note/name/View
插入:POST请求
插入数据:http://192.168.43.60:8089/api/android/note
修改:PUT请求
修改id=1的数据:http://192.168.43.60:8089/api/android/note/1
删除:DELETE请求
删除id=1的数据:http://192.168.43.60:8089/api/android/note/1
2. Отображение SQL с использованием встроенного запроса и нечеткого запроса выглядит следующим образом:
Операции dao, Service и Controller аналогичны, поэтому я не буду их публиковать.
<select id="findALL" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
</select>
<select id="findByType" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE a.type=#{type}
</select>
<select id="findById" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE a.id=#{id}
</select>
<select id="findByName" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
where name LIKE concat(concat('%',#{name}),'%')
</select>
3. Доступ к ресурсам сервера
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//在F:/SpringBootFiles/Image/下如果有一张 Excalibar.jpg的图片,那么:
//【1】访问:http://localhost:8080/imgs/Excalibar.jpg 可以访问到
//【2】html 中 <img src="imgs/Excalibar.jpg">
registry.addResourceHandler("/imgs/**").addResourceLocations("file:F:/SpringBootFiles/imgs/");
registry.addResourceHandler("/mp3/**").addResourceLocations("file:F:/SpringBootFiles/mp3/");
registry.addResourceHandler("/file/**").addResourceLocations("file:F:/SpringBootFiles/file/");
}
}
4. Интерфейс загрузки файлов:UploadController.java
表单上传:http://192.168.43.60:8089/api/android/upload
写流上传:http://192.168.43.60:8089/api/android/postfile
//注意,SpringBoot中表单上传有限定大小2M,修改方式:
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
@RestController
@RequestMapping(value = "/api/android")
public class UploadController {
/**
* 表单上传:多文件上传(包括一个)
*
* @param files 上传的文件
* @return 上传反馈信息
*/
@PostMapping(value = "/upload")
public @ResponseBody
ResultBean uploadImg(@RequestParam("file") List<MultipartFile> files) {
StringBuilder result = new StringBuilder();
for (MultipartFile file : files) {
if (file.isEmpty()) {
return ResultHandler.error("Upload Error");
}
String fileName = file.getOriginalFilename();//获取名字
String path = "F:/SpringBootFiles/imgs/";
File dest = new File(path + "/" + fileName);
if (!dest.getParentFile().exists()) { //判断文件父目录是否存在
dest.getParentFile().mkdir();
}
try {
file.transferTo(dest); //保存文件
result.append(fileName).append("上传成功!\n");
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
result.append(fileName).append("上传失败!\n");
}
}
return ResultHandler.ok(result.toString());
}
/**
* 通过流写入服务器
* @param name
* @param request
* @return
*/
@PostMapping(value = "/postfile")
public @ResponseBody
ResultBean postFile(@RequestParam(value = "name") String name, HttpServletRequest request) {
String result = "";
ServletInputStream is = null;
FileOutputStream fos = null;
try {
File file = new File("F:/SpringBootFiles/imgs", name);
fos = new FileOutputStream(file);
is = request.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
result = "SUCCESS";
} catch (IOException e) {
e.printStackTrace();
result = "ERROR";
} finally {
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return ResultHandler.ok(result);
}
}
4. Междоменная обработка
Основная проблема заключается в том, что проблема заголовка перекрестного доменного запроса, подробный анализ показывает:SpringBoot-12-Полный анализ междоменного доступа Ajax
AndroidProjectApplication
@SpringBootApplication
//坑点5:将dao添加扫包范围
@MapperScan(basePackages = {"toly1994.com.android_project.dao"})
public class AndroidProjectApplication {
public static void main(String[] args) {
SpringApplication.run(AndroidProjectApplication.class, args);
}
@Bean
public FilterRegistrationBean registerFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.addUrlPatterns("/*");//所有请求都经过这个Filter
bean.setFilter(new CrosFilter());//设置过滤器
return bean;
}
}
toly1994.com.android_project.config.CrosFilter
/**
* 作者:张风捷特烈
* 时间:2018/7/22:21:44
* 邮箱:1981462002@qq.com
* 说明:解决跨域问题...加头
*/
public class CrosFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse rep = (HttpServletResponse) servletResponse;
HttpServletRequest req = (HttpServletRequest) servletRequest;
String origin = req.getHeader("Origin");
if (!StringUtils.isEmpty(origin)) {
rep.addHeader("Access-Control-Allow-Origin", origin);
}
//动态添加自定义头
String headers = req.getHeader("Access-Control-Request-Headers");
if (!StringUtils.isEmpty(headers)) {
System.out.println(headers);
rep.addHeader("Access-Control-Allow-Headers", headers);
}
//允许8081访问:
// rep.addHeader("Access-Control-Allow-Origin", "*");
// rep.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
//允许访问方法GET
rep.addHeader("Access-Control-Allow-Methods", "GET");
rep.addHeader("Access-Control-Allow-Methods", "POST");
// rep.addHeader("Access-Control-Allow-Headers", "Content-Type");
rep.addHeader("Access-Control-Max-Age", "3600");//一小时内缓存预检请求
rep.addHeader("Access-Control-Allow-Credentials", "true");//允许cookie
filterChain.doFilter(servletRequest, rep);
}
@Override
public void destroy() {
}
}
В-четвертых, локальный проект SpringBoot развертывается на сервере для запуска (с использованием Tencent Cloud).
1. Упаковка:
Я изменил порт на 8089 (потому что мой сервер открыл порт 8089)
mvn -Dmaven.test.skip -U clean install
2. Резервное копирование и восстановление базы данных
Локальное резервное копирование, восстановление сервера
备份:mysqldump -uroot -p mycode >D:\\backupSql\\android.sql
还原:mysql -u root -p mycode< D:\\backupSql\\android.sql
3. Онлайн
бегать:
F:\>java -jar F:\android_project-0.0.1-SNAPSHOT.jar
4. Протестируйте API-интерфейс URL-адреса
1) Добавить: ПОСТ:Woohoo.для использования 1994.com:8089/API/Android…
2) Запрос:Woohoo.для использования 1994.com:8089/API/Android…
3) Доступ к картинкам
До сих пор была реализована простая работа внутренней базы данных и API-интерфейса RESTFUL, хотя это относительно просто.
Вы можете добавить другие URL-адреса, если это необходимо позже, интерфейс доступа имеет данные, а бэкэнд подошёл к концу.
2018-12-12 Дополнение: Добавить пейджинговый запрос:
Смещение 0, 20 штук данных на странице:
http://192.168.43.60:8089/api/android/note/0/20
<select id="findByType" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,info,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE a.type=#{type}
limit #{offset},#{limit}
</select>
Пагинация запроса категории:
http://192.168.43.60:8089/api/android/note/type/ABCS/0/4
<select id="findByName" resultType="toly1994.com.android_project.bean.Note">
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,info,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
where name LIKE concat(concat('%',#{name}),'%')
limit #{offset},#{limit}
</select>
Далее: Python Crawler + подготовка данных (селен)
Постскриптум: чешский стандарт
1. История роста и опечатки этой статьи
| Исходный код проекта | Дата | Примечание |
|---|---|---|
| V0.1 | 2018-12-11 | Внутренний интерфейс четырех шагов создания веб-сайта (SpringBoot+ онлайн) |
| V0.2 | 2018-12-12 | Обработка запроса пейджинга, добавление информационного поля |
2. Подробнее обо мне
| псевдоним | Хобби | ||
|---|---|---|---|
| Чжан Фэнцзетли | 1981462002 | zdl1994328 | язык |
| мой гитхаб | моя краткая книга | Мои самородки | персональный сайт |
3. Заявление
1 ----Эта статья была первоначально написана Чжан Фэнцзетли, пожалуйста, укажите при перепечатке
2 ----Приглашаем энтузиастов программирования общаться друг с другом
3 ---- Личные способности ограничены, если что-то не так, вы можете критиковать и свидетельствовать, и вы должны смиренно исправить это.
4 ---- Видя это, я благодарю вас за вашу любовь и поддержку