Начало работы с Java Web Basics

Java API Android gradle

автор:@Ryan-Miao
Данная статья является оригинальной автором, при перепечатке просьба указывать источник:Блог Woohoo.cn на.com/Я Муронгфу/Боюсь/…


содержание

RESTfull API
ContentType
NodeJS Web
Java Web
demo source
Что такое Грейдл
IntelIj IDEA
Создайте новый проект градиента
Начать писать конфигурацию сервера
Напишите свой первый API
Запуск и отладка
конфигурационный файл
Получить параметры, ответить JSON
проверка параметров
статические файлы
файл шаблона
перекрестный домен
развертывать
Представьте MySQL
JDBCTemplate
Многоуровневая архитектура
DI
интерфейсно-ориентированное программирование
писать тесты
Интегрированный CI
перехват входа в систему
OAuth2.0
вещь
JPA
тайник

предисловие

Языки все одинаковые, пока вы понимаете концепции, вы можете писать код. Концепция заключается в необходимости узнать стоимость.

Основы Java

Не смотрите на «Мышление программирования», смотрите на базовую грамматикуооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо…Вот и все, делайте все, что хотите, после начала, если вам интересно, если у вас есть время.

Web

Упомянутая здесь сеть относится к способности предоставлять API (интерфейс прикладного программирования). Так что же такое API?

API относится к каналу взаимодействия ресурсов между серверной и клиентской сторонами. Клиент может получать и модифицировать ресурсы на стороне сервера через API, по сути, API — это почти название URL, на данном этапе рекомендуется использовать RESTfull API.

RESTfull API

Представление API — это URL (унифицированный указатель ресурсов). RESTful API — это концепция, определяющая, какую структуру следует использовать для создания API, то есть как объединять URL-адреса. Давайте посмотрим, как выглядит URL.

Ресурсы
в путиgroupsиusersОба являются именем ресурса, а расположение ресурса определяется параметрами.

Поведение/операция (метод)
мы согласилисьHttp Methodдля представления операций над ресурсом.

Существует пять часто используемых глаголов HTTP (соответствующие команды SQL указаны в скобках).

GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。скопировать код

Есть также два менее часто используемых HTTP-глагола.

HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。скопировать код

Пример:

GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物скопировать код

Когда состав пути по-прежнему не может точно определить местонахождение ресурса, можно использовать параметр queryParam для дальнейшего сужения области.

?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page=2&per_page=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件скопировать код

Для получения дополнительной информации о создании RESTfull API см. https://codeplanet.io/principles-good-restful-api-design/

ContentType

Текущий интерфейс основан на передаче JSON. Что такое JSON (нотация объектов JavaScript)?

Ответ API на основе JSON должен содержать следующие заголовки.

Content-Type:application/json; charset=utf-8скопировать код

NodeJS Web

УстановитьNodeJS

Затем создайте app.js,npm install express --save, node app.js, доступlocalhost:3000/,localhost:3000/json

// 这句的意思就是引入 `express` 模块,并将它赋予 `express` 这个变量等待使用。
var express = require('express');
// 调用 express 实例,它是一个函数,不带参数调用时,会返回一个 express 实例,将这个变量赋予 app 变量。
var app = express();

// app 本身有很多方法,其中包括最常用的 get、post、put/patch、delete,在这里我们调用其中的 get 方法,为我们的 `/` 路径指定一个 handler 函数。
// 这个 handler 函数会接收 req 和 res 两个对象,他们分别是请求的 request 和 response。
// request 中包含了浏览器传来的各种信息,比如 query 啊,body 啊,headers 啊之类的,都可以通过 req 对象访问到。
// res 对象,我们一般不从里面取信息,而是通过它来定制我们向浏览器输出的信息,比如 header 信息,比如想要向浏览器输出的内容。这里我们调用了它的 #send 方法,向浏览器输出一个字符串。
app.get('/', function (req, res) {
  res.send('Hello World');
});

app.get('/json', function (req, res) {
  var rs = {};
  rs.id=1;
  rs.name = "Ryan";
  
  res.send(rs);
});

// 定义好我们 app 的行为之后,让它监听本地的 3000 端口。这里的第二个函数是个回调函数,会在 listen 动作成功后执行,我们这里执行了一个命令行输出操作,告诉我们监听动作已完成。
app.listen(3000, function () {
  console.log('app is listening at port 3000');
});скопировать код

Java Web

Среди фреймворков Java Web с открытым исходным кодом в настоящее время наиболее часто используется SpringBoot, который может предоставлять API и отображать страницы, что является лучшим выбором в качестве сервера API.

Я бесчисленное количество раз писал hello world, но на этот раз я должен начать с hello world.

demo source

GitHub.com/Ryan-Mia O/ это…

Инструменты управления веб-пакетами Java включают maven и gradle. Здесь мы будем использовать gradle как инструмент управления зависимостями.

Что такое Грейдл

gradleЭто интегратор инструментов построения Java-проектов после maven. Он управляет зависимостями, зачем управлять зависимостями? В нашем проекте будет использоваться много других библиотек, эти библиотеки наши собственные, некоторые из них с открытым исходным кодом, и даже большинство из них с открытым исходным кодом. Когда были представлены эти библиотеки, какая версия была представлена? Где скачать? Что делать, если есть конфликты между несколькими версиями? И, наконец, после завершения разработки нашего проекта, как его упаковать? Даже если вы хотите использовать CI/CD для автоматизации инструментов сборки, как интегрировать? Это то, что может сделать Gradle.

Как выучить градл?

Вообще говоря, вам не нужно учиться, не заботьтесь о встроенной логике, просто используйте ее. Это как IDE, вы не вникаете в то, написана ли IDE на C или Java, но вы используете IDE для написания кода. Точно так же использование gradle очень простое, и оно может удовлетворить некоторые наши потребности в разработке. Конечно, когда вам нужны пользовательские функции, вы можете использоватьgroovyдля написания сценариев градации.

IntelIj IDEA

В настоящее время IDEA является самой популярной IDE для создания веб-проектов Java. Между использованием и Eclipse все еще есть много различий, и это может быть немного непривычно, когда вы только что перевернули его. Но в соответствии с принципом 2-8 нам нужно освоить только некоторые из способов использования для разработки, а остальные продвинутые способы использования можно изучать медленно в процессе разработки. То есть использование на самом деле довольно простое.

Создайте новый проект градиента

нажмитеFile->New->project->gradle-> поставить галочкуJava

Если вы обнаружите, что JDK нет, то подойдет новый.

Затем установите метку проекта, группа обычно является обратной от названия компании, напримерcom.google,com.alibabaи т.д. ArtifactId — это название нашего проекта, например, это демоspringboot-demo

Затем полностью перейти к следующему и подтвердить после завершения. IDEA загрузит gradle, загрузит простые зависимости, и после завершения в корневом каталоге проекта будет еще несколько файлов, поэтому в настоящее время нет необходимости заботиться.

.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   └── resources
    └── test
        ├── java
        └── resources
скопировать код

Изменить следующийbuild.gradle, этот файл является основным файлом для управления зависимостями

buildscript {
    repositories {
        maven {
            url "http://maven.aliyun.com/nexus/content/groups/public/"
        }
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'springboot-demo'
    version =  '0.1.0'
}

repositories {
    maven {
        url "http://maven.aliyun.com/nexus/content/groups/public/"
    }
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile('org.springframework.boot:spring-boot-starter-test')
}скопировать код
  • Maven - это склад, и некоторые библиотеки сторонних библиотек с открытым исходным кодом загружаются отсюда. Образ aliyun цитируется здесь, потому что доступ к maven относительно медленный в Китае. Если вы находитесь за границей, вы можете удалить этот узел.
  • buildscriptЭто написано так, не беспокойтесь о том, почему, просто знайте, что версию springboot можно импортировать, написав так
  • dependenciesЭто единственное место, где содержимое будет изменено и добавлено.Когда необходима сторонняя библиотека, правило добавленияgroupId:artifactId:version, точно такой же, как метка, которую мы объявили при создании проекта

Исправлятьbuild.gradleПосле этого необходимо пересобрать.В IDEA нажмите на панель инструментов справа, град и нажмите кнопку обновить. Он автоматически загрузит зависимости.Если он не загружен, нажмите «Задача в градиенте».buildкнопка.

Другой способ — командная строка:

Осторожно, вы можете обнаружить, что естьgradlewиgradlew.batЭтот файл, который является средством запуска для Linux и Windows, соответственно, в системе Linux.

./gradlew build
or
sh gradlew buildскопировать код

в окнах

gradlew buildскопировать код

После завершения компиляции в каталоге проекта слеваExternal LibratiesНиже вы можете увидеть сторонние библиотеки, которые мы представили. Почему так много? Потому что зависимости бывают древовидными или сетевыми. lib также имеет свои собственные зависимости, и gradle будет отвечать за загрузку зависимостей представленной нами библиотеки. Прежде чем не будет инструментов сборки, таких как maven и gradle, разработка проекта заключается в том, чтобы загружать jar-файлы сами по себе и добавлять их в путь к классам, что легко пропустить и легко вызвать конфликты. gralde будет отвечать за загрузку зависимостей и разрешение конфликтов, таких как разные версии.

Начать писать конфигурацию сервера

Одним из преимуществ Springboot является то, что соглашение больше, чем конфигурация, а это означает, что мы все согласны с тем, как его настроить Я настрою его для вас, и вы сможете использовать его напрямую. Поэтому большую часть конфигурации в эпоху springmvc можно автоматизировать. Наш класс запуска также имеет только одну строку.

можно увидеть,src/main/javaЭтот каталог становится синим.В IDEA он относится к sourceSet, который является исходным файлом.Наш Java-код размещается под этим файлом, что также согласовано.

Создайте новый в этом каталогеcom.test.demo.Application.java

package com.test.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Created by Ryan on 2017/11/13/0013.
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}скопировать код

На этом настройка нашего сервера завершена. Запустите основной метод, чтобы начать.

Напишите свой первый API

Хоть сервер и настроен, но API нет.com.test.demo.controller.HelloController.java

package com.test.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Created by Ryan on 2017/11/14/0014.
 */
@Controller
public class HelloController {
    

    @ResponseBody
    @GetMapping("/hello")
    public String hello(){
        return "{\"hello\":\"world\"}";
    }
}скопировать код

Затем снова запустите основной метод, после запуска получите доступhttp://localhost:8080/hello, разработан первый API.

  • @ControllerЭта аннотация помечает этот класс как контроллер, который получает запросы и отвечает на ответы.
  • @GetMapping("/hello")Отметьте этот метод как реализацию запроса маршрутизации, а скобки — нашу маршрутизацию.
  • @ResponseBodyЭта аннотация указывает на то, что возвращаемое значение этого API — json, на самом деле contentType вставляется в заголовок ответа, конечно, здесь также задействована проблема преобразования класса в json. Итак, вернемся к вопросу в начале, что такое json?

JSON не имеет такой структуры данных в Java. На самом деле это строка, которая следует правилам JSON. Когда наш метод возвращает эту строку, а также contentType в заголовке, браузер будет читать ее как JSON. Результат чтения Ajax в Javascript становится объектом JSON. Другие, такие как Android, считывают строку, которую необходимо вручную десериализовать в нужный нам класс.

Говоря о сериализации, мы не можем объединять такие строки для каждой возвращаемой структуры. так,ResponseBodyАннотированные запросы также используют адаптер Джексона, встроенный в Springboot. Пока нет необходимости изучать принцип реализации. какой к черту джексон?

jackson — это наиболее широко используемая библиотека для анализа json в Java, которая может преобразовывать класс Java в строку json, а также десериализовать строку json в объект java. Как это делает Springboot? Это требует изучения исходного кода.

Запуск и отладка

Самый простой способ запуска — запустить основной метод, также можно запустить из командной строки.

gradlew bootRunскопировать код

Для отладки проще всего запустить основной метод с отладкой. Конечно же и дистанционно.

gradlew bootRun --debug-jvmскопировать код

Затем в IDEA нажмите «Изменить конфигурации».

выбрать удаленный

Затем нажмите отладить

Если вы хотите поддерживать горячую загрузку, вам нужно добавить

compile("org.springframework.boot:spring-boot-devtools")скопировать код

После изменения класса Java в IDEA вам необходимо перестроить текущий класс, чтобы изменения вступили в силу. горячая клавишаctrl+shif+F9

конфигурационный файл

Spring boot по умолчанию настроен со многими вещами, но иногда мы хотим изменить значения по умолчанию, например, мы не хотим использовать 8080 в качестве порта, потому что порт занят.

существуетresourcesвниз, новыйapplication.properties, а затем введите

server.port=8081скопировать код

Затем перезапустите проект и обнаружите, что порт вступил в силу.

Настройте некоторые общие настройки, такие как журналы. Проект должен записывать журнал,System.out.printlnДалеко не соответствует требованиям журнала. Springboot по умолчаниюLogbackкак средство обработки логов.

spring.output.ansi.enabled=ALWAYS
logging.file=logs/demo.log
logging.level.root=INFOскопировать код

Далее, конфигурация среды разработки и производственной среды должна быть разной, например, адреса баз данных разные, поэтому файлы конфигурации можно использовать для различения сред.

Создайте новый в ресурсахapplication-dev.properties, application-prod.properties, Spring по умолчанию распознает разные среды по разным суффиксам и базовой конфигурации без суффикса. Итак, как это работает?

пока в базовом файле конфигурации

spring.profiles.active=devскопировать код

Например, мы устанавливаем loglevel для отладки в среде разработки.

logging.level.root=debugскопировать код

Таким образом, springboot сначала прочитает базовый файл, а затем прочитает dev.Когда dev имеет тот же элемент конфигурации, dev перезапишет базу.

Таким образом, локальная среда разработки и производственная среда изолированы, а развертывание также удобно. На самом деле приоритет получения параметров springboot равенresources下的配置文件<命令行参数Обычно наши сценарии для развертывания проектов используют аргументы командной строки для переопределения файлов конфигурации, чтобы файлы конфигурации можно было указывать динамически.

Получить параметры, ответить JSON

Создайте новый контроллер, com.test.demo.controller.ParamController.

package com.test.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Ryan on 2017/11/16/0016.
 */
@RestController
@RequestMapping("/param")
public class ParamController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ParamController.class);

    @GetMapping("/hotels/{htid}/rooms")
    public List<Long> getRooms(
            @PathVariable String htid,
            @RequestParam String langId,
            @RequestParam(value = "limit", required = false, defaultValue = "10") int limit,
            @RequestParam(value = "offset", required = false, defaultValue = "1") int offset
    ){
        final Map<String, Object> params = new HashMap<>();
        params.put("hotelId", htid);
        params.put("langId", langId);
        params.put("limit", limit);
        params.put("offset", offset);

        LOGGER.info("The params is {}", params);

        List<Long> roomIds = new ArrayList<>();
        roomIds.add(1L);
        roomIds.add(2L);
        roomIds.add(3L);

        return roomIds;
    }
}скопировать код
  • LOG: принять интерфейс Sl4J
  • параметр:@PathVariableМожет получать параметры в URL-адресе
  • параметр:@RequestParamможет получить?после параметра запроса
  • отклик:@RestController == @Controller+@ResponseBody, фактически,@ResponseBodyВ аннотации указано, что этот метод вернет json, который преобразует класс Java в строку JSON.Преобразователь по умолчанию — Джексон.

Параметр JSON

Новый класс com.test.demo.entity.Room

public class Room {
    private Integer roomId;
    private String roomName;
    private String comment;

    public Integer getRoomId() {
        return roomId;
    }

    public void setRoomId(Integer roomId) {
        this.roomId = roomId;
    }

    public String getRoomName() {
        return roomName;
    }

    public void setRoomName(String roomName) {
        this.roomName = roomName;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }
}скопировать код

Предположим, нам нужно сохранить информацию о комнате, сначала получите один

@GetMapping("/hotels/{htid}/rooms/{roomId}")
public Room getRoomById(
        @PathVariable String htid,
        @PathVariable Integer roomId
){

    if (htid.equals("6606")){
        final Room room = new Room();
        room.setComment("None");
        room.setRoomId(roomId);
        room.setRoomName("豪华双人间");

        return room;
    }

    return null;
}скопировать код

затем сохраните

@PostMapping("/hotels/{htid}/rooms")
public Integer addRoom(@RequestBody Room room){
    final Random random = new Random();
    final int id = random.nextInt(10);
    room.setRoomId(id);

    LOGGER.info("Add a room: {}", room);

    return id;
}скопировать код

получить параметр массива

@GetMapping("/hotels/{htid}/rooms/ids")
public String getRoomsWithIds(@RequestParam List<Integer> ids){
    String s = ids.toString();
    LOGGER.info(s);
    return s;
}скопировать код

доступ через браузерhttp://localhost:8081/param//hotels/6606/rooms/ids?ids=1,2,3

проверка параметров

В дополнение к оценке параметров по одному, если мы также можем использовать аннотации

public class Room {
    private Integer roomId;
    @NotEmpty
    @Size(min = 3, max = 20, message = "The size of room name should between 3 and 20")
    private String roomName;скопировать код

Просто добавьте перед параметромjavax.validation.Valid

@PostMapping("/hotels/{htid}/rooms")
    public Integer addRoom(
           @Valid @RequestBody Room room,
            @RequestHeader(name = "transactionId") String transactionId
    ){скопировать код

статические файлы

В springboot правило поиска по умолчанию для статического контента:

By default Spring Boot will serve static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.

существуетresourcesновая папка подstatic,
src\main\resources\static\content.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello static content</title>
    <script src="/js/test.js"></script>
</head>


<body>
<h1>Static Content</h1>

<p>Static content is the files that render directly, the file is the whole content. The different between template is that
the template page will be resolved by server and then render out.
</p>
</body>
</html>скопировать код

Доступ через браузер:http://localhost:8081/content.html

Точно так же через это сопоставление можно получить доступ к файлам, помещенным в static.

файл шаблона

Файлы шаблонов относятся к файлам, сгенерированным сервером. Например, Jsp будет скомпилирован сервлетом и, наконец, сгенерирует html-страницу. Springboot по умолчанию поддерживает следующие шаблоны:

FreeMarker
Groovy
Thymeleaf
Mustache

Существует проблема с поведением JSP в файлах jar, если они не развернуты как война.

Официальный рекомендуемый шаблон:Thymeleaf, добавить зависимости в зависимости:

compile("org.springframework.boot:spring-boot-starter-thymeleaf")скопировать код

rebuild.

Расположение файла шаблона SpringBoot по умолчанию для чтения:src\main\resources\templates. Новыйsrc\main\resources\templates\home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta charset="UTF-8"/>
    <title>Home</title>
</head>
<body>
<h1>Template content</h1>

<p th:text="${msg} + ' The current user is:' + ${user.name}">Welcome!</p>


</body>
</html>скопировать код

Файлы шаблонов могут быть обработаны только через маршрутизацию на стороне сервера, что означает, что они не могут быть маршрутизированы напрямую, как статические файлы в начале.

Создайте контроллер,com.test.demo.controller.HomeController

package com.test.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Ryan on 2017/11/18/0018.
 */
@Controller
public class HomeController {

    @RequestMapping("/home")
    public String index(Model model, String name){
        final Map<String, Object> user = new HashMap<>();
        user.put("name", name);

        model.addAttribute("user", user);
        model.addAttribute("msg", "Hello World!");
        return "home";
    }
}скопировать код

Этот интерфейс немного отличается от предыдущего API, во-первых, нет@ResponseBodyАннотация, то возвращаемое значение метода является строкой, эта строка не является значением, а относится к расположению файла шаблона относительноtemplatesпозиция.

Доступ через браузер:http://localhost:8081/home?name=Ryan123

параметр методаModelЭто переменный источник файла шаблона.Файл шаблона считывает переменную из этого объекта и помещает класс в параметр.Spring автоматически внедрит этот класс и привяжет его к файлу шаблона. Здесь введите две переменные.

На стороне шаблона эту переменную можно прочитать.

почему ты хочешь сделать это? Зачем вам нужны файлы шаблонов, если у вас есть статические файлы?

Во-первых, это практика ранней веб-разработки, веб-интерфейса раньше не было, страница менялась со статической страницы на динамическую, которая представляла собой jsp, php и т.д. Одним из преимуществ файла шаблона является то, что сервер может управлять страницей, например получать информацию о пользователе из сеанса и размещать ее на странице. Это невозможно на статических страницах.

Однако текущая практика разделения клиентской и серверной частей делает роль файлов шаблонов все меньше и меньше. В настоящее время он в основном используется для базовой передачи данных, а остальные данные получаются посредством асинхронного запроса клиента.

Конечно, из-за сложности построения страницы и слишком большого количества асинхронных запросов время рендеринга первого экрана становится все больше и больше, что серьезно влияет на пользовательский опыт, например рекламную страницу Taobao Double 11. В настоящее время снова проявляются преимущества рендеринга на стороне сервера: статические страницы напрямую выводят данные без многочисленных Ajax-запросов.

перекрестный домен

Cross-origin resource sharing (CORS) is a W3C specification implemented by most browsers that allows you to specify in a flexible way what kind of cross domain requests are authorized, instead of using some less secure and less powerful approaches like IFRAME or JSONP.

CORS — это защита безопасности для браузеров, которая изолирует видимость между разными доменами. Например, нельзя отправлять куки под этим доменным именем на другое доменное имя, иначе после фишинга куки хакер может войти в систему, выдавая себя за себя. Более подробная информацияMDN

Почему браузеры отвергают cors?
Взято изБлог Парк

Процесс выполнения cors взят изБесплатная Википедия

Сначала локально моделируется междоменный запрос.

Доменное имя нашей текущей демонстрации:localhost:8081, теперь добавьте локальное доменное имя, добавьте в файл HOSTS:

127.0.0.1   corshostскопировать код

Затем посетите http://corshost:8081, это демонстрация.

Добавлен src\main\resources\static\cors.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Cors</title>
</head>
<body>

<script src="http://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>

<script>
    $.ajax({ url: "http://localhost:8081/hello", success: function(data){
        console.log(data);
    }});
</script>
</body>
</html>скопировать код

Получите доступ к приветственному интерфейсу, созданному ранее, вы можете увидеть, что доступ не работает,

Failed to load http://localhost:8081/hello: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://corshost:8081' is therefore not allowed access.скопировать код

Это нормальное поведение браузера.

Однако из-за разделения front-end и back-end или даже отдельного развертывания доменное имя точно не будет одинаковым, поэтому необходимо поддерживать кроссдоменность. Springboot поддерживает кроссдоменность, решение таково:

В методе, который должен быть междоменным, добавьте@CrossOriginПросто аннотируйте.

@CrossOrigin(origins = {"http://corshost:8081"})
@ResponseBody
@GetMapping("/hello")
public String hello(){
    return "{\"hello\":\"world\"}";
}скопировать код

Если глобальная конфигурация допускает междоменный доступ, создайте новый.com.test.demo.config.CorsConfiguration

package com.test.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * Created by Ryan on 2017/11/18/0018.
 */
@Configuration
public class CorsConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                        .allowedOrigins("http://domain2.com")
                        .allowedMethods("PUT", "DELETE")
                        .allowedHeaders("header1", "header2", "header3")
                        .exposedHeaders("header1", "header2")
                        .allowCredentials(false).maxAge(3600);
            }
        };
    }
}
скопировать код

развертывать

Представьте MySQL

JDBCTemplate

Многоуровневая архитектура

DI

интерфейсно-ориентированное программирование

писать тесты

Интегрированный CI

перехват входа в систему

OAuth2.0

вещь

JPA

тайник

Ссылаться на

So do it,and change it,no regret!