INFO
остальное c FATAL
logback.xml
д б в src/main/resurces
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<variable name="BASEDIR" value="${BASEDIR:-.}"/>
<!-- https://www.cloudesire.com/configure-logback-log-level-via-environment-variables/ -->
<property name="FILENAME" value="App"/>
<property name="DIR" value="${BASEDIR}/logs"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- can use ${APP_HOME} -->
<file>${DIR}/${FILENAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${DIR}/${FILENAME}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>100KB</maxFileSize>
<totalSizeCap>1MB</totalSizeCap>
<maxHistory>1</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
<logger name="example" level="DEBUG" additivity="false">
<appender-ref ref="FILE"/>
</logger>
<logger name="org.springframework.data" level="FATAL"/>
<logger name="org.hibernate" level="FATAL"/>
<logger name="org.hibernate.hql" level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
<logger name="org.springframework.jdbc.core" level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
</configuration>
package example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final static String username = "admin";
private final static String password = "password";
@Autowired
private BasicAuthenticationPoint basicAuthenticationPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/", "/api/**").permitAll()
.anyRequest().authenticated();
http.httpBasic().authenticationEntryPoint(basicAuthenticationPoint);
}
// https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-format
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser(username)
.password(String.format("{noop}%s", password)).roles("USER");
}
}
package example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class BasicAuthenticationPoint extends BasicAuthenticationEntryPoint {
private static final String realName = "user";
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException e) throws IOException {
response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 - " + e.getMessage());
}
@Override
public void afterPropertiesSet() {
setRealmName(realName);
super.afterPropertiesSet();
}
}
mvn -Dmaven.test.skip=true clean spring-boot:run
curl --silent http://localhost:8080/
HTTP Status 401 - Full authentication is required to access this resource
curl --silent --user admin:wrong_password http://localhost:8080/employees
HTTP Status 401 - Bad credentials
curl -silent --user admin:password http://localhost:8080/employees
HTTP Status 200 OK
...
то что контроллер должен ответить
Basic YWRtaW46cGFzc3dvcmQ=
echo 'YWRtaW46cGFzc3dvcmQ=' | base64 -d -
admin:password
import javax.validation.Valid;
@RestController
public class MainController
{
@PostMapping("/proxy/add")
public void saveProxy(@Valid @RequestBody ProxyDto dto) {
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@RestController
@RequestMapping("/proxy")
public class MainController
{
@RequestMapping(value = "add", method = RequestMethod.POST)
public Map<String, Object> addBook(@Validated @RequestBody ProxyDto dto ) {
....
и import javax.validation.constraints.NotNull;
public class ProxyDto {
@NotNull(message = "idbn is missing")
@NotEmpty(message = "idbn is empty")
private String proxy;
{
"timestamp": 1612029070201,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
"errors": [
{
"codes": [
"NotNull.book.isbn",
"NotNull.isbn",
"NotNull.java.lang.String",
"NotNull"
],
"arguments": [
{
"codes": [
"book.isbn",
"isbn"
],
"arguments": null,
"defaultMessage": "isbn",
"code": "isbn"
}
],
"defaultMessage": "idbn is missing",
"objectName": "book",
"field": "isbn",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotNull"
},
{
"codes": [
"NotEmpty.book.isbn",
"NotEmpty.isbn",
"NotEmpty.java.lang.String",
"NotEmpty"
],
"arguments": [
{
"codes": [
"book.isbn",
"isbn"
],
"arguments": null,
"defaultMessage": "isbn",
"code": "isbn"
}
],
"defaultMessage": "idbn is empty",
"objectName": "book",
"field": "isbn",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotEmpty"
}
],
"message": "Validation failed for object='book'. Error count: 2",
"path": "/book/add"
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>static_page</artifactId>
<version>0.4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>static_page</name>
<description>Springboot Template page Demo project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<finalName>${project.groupId}.${project.artifactId}</finalName>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<thymeleaf.version>3.0.6.RELEASE</thymeleaf.version>
<thymeleaf-extras-java8time.version>3.0.0.RELEASE</thymeleaf-extras-java8time.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
<assertj.version>3.8.0</assertj.version>
<webjars.bootstrap.version>3.3.7</webjars.bootstrap.version>
<webjars.jquery.version>3.2.1</webjars.jquery.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${webjars.bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>${webjars.jquery.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.owasp.antisamy</groupId>
<artifactId>antisamy</artifactId>
<version>1.5.9</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.13.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${finalName}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>
package ru.belov.spring.config.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/design")
public class DesignTacoController {
@GetMapping
public String showDesignForm(Model model) {
return "design";
}
}
package ru.belov.spring.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
mkdir -p src/main/resources/templates
mv src/main/webapp/WEB-INF/views/design.html src/main/resources/templates/
th
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="@{/styles.css}" />
</head>
<body>
<h1>Design your taco!</h1>
<img th:src="@{/images/tako.png}"/>
</body>
</html>
mvn clean spring-boot:run
docker run -v ${HOME}/Desktop/:/var/properties -p 8086:8080 basic-example
curl http://localhost:8085/basic
Hello some value
sed -i 's|some value|some other value|' ~/Desktop/application.properties
curl http://localhost:8085/basic
Hello some other value
src\main\resources\application.properties
?Properties properties = new Properties();
InputStream input = null;
try {
input = <имя вашего класса>.class.getClassLoader()
.getResourceAsStream("application.properties");
properties .load(input);
System.err.println(properties .getProperty("spring.h2.console.enabled"));
throw new ResponseStatusException(HttpStatus.NOT_FOUND /* 404 */, "my message", new Exception(/* еще детали о том что случ лось */));
mvn clean spring-boot:run
src/main/java/Procfile
в котором написаноworker: sh target/bin/commybot
./mvnw
?.travis.yml
install: mvn install -DskipTests=true -Dgpg.skip=true -Dmaven.javadoc.skip=true -B -V
а не свои собственные скрипты