FHTTP: простой и удобный Java HTTP-фреймворк
FHTTP отказывается от существующих веб-серверов, начиная с Serversocket, и напрямую строит HTTP-сервис, создавая HTTP-сервер с нуля. Он предоставляет пользователям простой способ использования.
Все данные внутри фреймворка полностью используют кодировку UTF-8 и не могут быть изменены.
Версия 1.3.2 и 1.3.3
В версиях 1.3.2 и 1.3.3 исправлены проблемы с искажением имён файлов на китайском языке в коммитах и другие ошибки.
Версия 1.3.1
Версия 1.3.1 исправила ошибку при загрузке файлов.
Версия 1.3 Новые функции:
response.getJwtBuilder().withClaim("userName", "root").withExpiresAt(
Date.from(LocalDateTime.now().plusHours(1).atZone(ZoneId.systemDefault()).toInstant()
));
response.setJwtPassord("123456789");
Фреймворк будет записывать сгенерированный токен в заголовок HTTP-запроса «Authorization». Для чтения верификатора используется аннотация @Token:
@Token("123456789")
public String handlerMain(Map<String, Claim> claimMap) {
if (claimMap.containsKey(key) && claimMap.get(key).asString().equals(value)) {
return "<h1>hello, world</h1>";
} else {
return "<h1>please login first</h1>";
}
}
Если метод помечен аннотацией @Token, фреймворк проверит наличие заголовка «Authorization» в запросе. Если заголовок найден, он будет проверен с помощью пароля, указанного в аннотации. В случае успешной проверки, если параметр содержит карту типа Map<String, Claim>, она будет передана функции. В противном случае будет возвращено 403 (ошибка авторизации).
@Raw
@Mapping("/image_raw")
public void handleRaw(OutputStream output) throws IOException {
output.write("HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\nTransfer-Encoding: chunked\r\n\r\n".getBytes(StandardCharsets.UTF_8));
var buffer = new byte[100];
try (var input = Test2.class.getClassLoader().getResourceAsStream("a.jpg")) {
int n;
while (true) {
assert input != null;
if ((n = input.read(buffer)) == - 1) break;
output.write((Integer.toHexString(n) + "\r\n").getBytes(StandardCharsets.UTF_8));
output.write(buffer, 0, n);
output.write("\r\n".getBytes(StandardCharsets.UTF_8));
}
}
output.write("0\r\n\r\n".getBytes(StandardCharsets.UTF_8));
}
После применения аннотации @Raw фреймворк всё равно анализирует параметры запроса и передаёт их методу. Однако любые операции с выходным потоком должны выполняться вручную через выходной поток сокета. 4. Версия 1.3 поддерживает следующий способ создания jar-файла:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Версия 1.2.2
Исправлена ошибка при загрузке JSON и добавлена поддержка просмотра необработанных данных загрузки.
Новые функции:
Версия 1.2.2 позволяет просматривать необработанные данные загрузки:
byte[] data = request.getRawData();
Версия 1.2.1
Поддерживает загрузку JSON через формы POST и просмотр имён файлов загружаемых форм.
Новые функции:
Версия 1.2.1 позволяет просматривать имена файлов загруженных форм:
request.getFileInputStream(key).getFileName();
Версия 1.2
Позволяет запускать фреймворк новым способом и поддерживает запуск из jar-файла.
Новые функции:
Чтобы запустить фреймворк версии 1.2, используйте следующий код:
new FHTTP(запуск класса.class).start();
Фреймворк использует каталог запуска класса в качестве корневого каталога и автоматически находит остальные классы. Рекомендуется использовать следующие maven-плагины для упаковки:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>Main</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>dependencies/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependencies/</outputDirectory>
``` ```
<includeScope>runtime</includeScope>
<useBaseVersion>true</useBaseVersion>
</configuration>
</execution>
Версия: 1.1.2 Пример метода обновления версии для получения файла, загруженного пользователем из формы: получение файла по имени «img» из формы:
try (var input = request.getFileInputStream("img")) {
output.write(input.readAllBytes());
// Получение файла MIME-типа
String mime = input.getMimeType();
}
}```
Версия: 1.1.1
**Исправлена проблема с загрузкой внутренних страниц 404 и 500**.
Версия: 1.1.0
**Добавлена обработка ошибок 404 и 500.**
## 404 и 500
Если не определена пользовательская функция обработки ошибок 404 или 500, то фреймворк будет использовать внутреннюю страницу 404 или 500.
Чтобы создать собственную страницу ошибки, необходимо определить в контроллере метод с аннотацией @Status («404 ...») или @Status («500 ...»).
Этот метод не должен иметь аннотацию @Mapping, а также должен возвращать HTML-страницу.
Рекомендуется определить только один метод для обработки ошибок 404 и 500.
Версия: 1.0.1
**Исправлено поведение метода head.**
Версия: 1.0
## Использование
### Запуск сервера
Для запуска сервера необходимо выполнить следующий код в методе main:
```new FHTTP(запуск класса.class).start(); // См. версию 1.2```
или
```new FHTTP("путь к проекту").start();```
(устарело)
Код запустит сервер с портом по умолчанию 8080. Если требуется изменить порт, можно использовать метод setPort класса FHTTP:
```var fhttp = new FHTTP(класс запуска.class); // См. версию 1.2
fhttp.setPort(8000);```
Получить текущий порт можно с помощью метода getPort.
### Создание контроллера
После запуска фреймворка он будет искать все классы с аннотацией @Controller и методы с аннотацией @Mapping.
Затем фреймворк сопоставит URL запроса с методом контроллера. Пример:
```java
@Controller
public class Test2 {
@Mapping("/")
public Object handleIndex() {
return something;
}
@Mapping("/x")
public void handleX() {
//TODO
}
}
При обращении к URL / будет вызван метод handleIndex, а при обращении к /x — handleX. Контроллер может быть связан с определённым URL путём добавления аннотации @Controller("/c1"):
public class Test2 {
@Mapping("/")
public Object handleIndex() {
return something;
}
@Mapping("/x")
public void handleX() {
//TODO
}
}
В этом случае для вызова handleIndex нужно обратиться к URL /c1/, а для вызова handleX — к /c1/x. Таким образом, разные контроллеры могут обрабатывать разные URL.
Методы контроллера могут различать HTTP-методы (GET, POST, PUT, DELETE, HEAD) с помощью соответствующих аннотаций. Например, если добавить аннотацию @Post к методу, то этот метод будет обрабатываться только при запросе POST. По умолчанию используется метод GET, если нет других аннотаций.
Методы с аннотацией @Mapping могут возвращать любой тип данных или void. Фреймворк обрабатывает возвращаемые значения следующим образом:
Фреймворк поддерживает следующие аннотации: @JSON, @MIME, @Status.
Добавив аннотацию @JSON к методу, можно указать, что возвращаемый объект может быть сериализован в JSON. Фреймворк использует библиотеку Google Gson для сериализации объекта и возвращает application/json.
С помощью аннотации @MIME можно задать MIME-тип возвращаемых данных. Например:
@MIME("text/javascript")
public Object handle() {return "";}
Не забудьте добавить аннотацию @Mapping!
По умолчанию фреймворк устанавливает статус ответа как 200 OK. Поэтому, если статус равен 200 OK, дополнительную аннотацию @Status можно не добавлять.
Фреймворк позволяет использовать методы с несколькими параметрами. Эти параметры соответствуют следующим правилам:
Response:
public Object handle(Response response) {return "";}
Request:
public Object handle(Request request) {return "";}
Оба параметра:
public Object handle(Request request, Response response) {return "";}
Не забывайте аннотацию @Mapping!
Param имеет три вида аннотаций: PathParam, UrlParam и BodyParam. Они соответствуют параметрам динамического маршрута, параметрам GET и параметрам POST соответственно. Пример использования:
/**
* Определение JavaBean
*/
public class User {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
@Controller
public class Test2 {
@Mapping("/name/:userName")
public Object handleIndex(@PathParam User user) {
// При URL /name/张三, user.userName равно "张三"
}
@Mapping("/name")
public void handleX(@UrlParam User user) {
// При URL /name?userName=张三 user.userName равно "张三"
}
@Post
@Mapping("/name")
public void handlePost(@BodyParam User user) {
// При использовании формы или JavaScript formdata body для POST-запроса, user.userName равно "张三".
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )