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>
jdbc_prefix = "mysql";
options = "allowMultiQueries=true&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";
"jdbc:" + jdbc_prefix+"://" + serverName + "/" + databaseName + "?" + options;
docker-compose.yml
:version: "3.7"
services:
app:
image: sample-java17-app
user: "${UID:-1000}:${GID:-1000}"
command: "java -jar /app/target/demo-2.7.5.jar"
volumes:
- .:/app
ports:
- "8585:8080"
environment:
UID: ${UID:-1000}
GID: ${GID:-1000}
$(id -u)
$(id -g)
в вашей машине@JsonNaming
annotation is used to choose the naming strategies for properties in serialization, overriding the default. Using the value element, we can specify any strategy, including custom ones.ResultSet resultSet = statement.executeQuery("SELECT count(*) as cnt FROM customers WHERE name = 'Bob' AND purchase = 'bike'");
resultSet.next(); // not first() with PGSL JDBC it is forward only cursor
final int cnt = resultSet.getInt(1);
System.out.println("cnt: " + cnt);
String query = "SELECT count(*) <> 0 FROM accounts WHERE username = 'bob';";
System.out.println("Executing count query: " + query);
ResultSet resultSet = connection.createStatement().executeQuery(query);
resultSet.next();
final boolean status = resultSet.getBoolean(1);
System.out.println("status: " + status);
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
while (!questions.isEmpty()) {
String question = questions.pop();
System.out.println(question);
String line = null;
while (line == null || line.isEmpty())
line = bufferedReader.readLine();
answer.add(line);
}
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"
}
Enum
import java.lang.Enum;
import java.lang.IllegalArgumentException;
public class EvalEnum {
enum MyEnum {
One(1), Two(2), Three(3);
private int code;
MyEnum(int code) {
this.code = code;
}
}
public static void main(String[] args) {
System.out.println(
String.format("%s in MyEnum? %b", args[0], isPresent(args[0])));
}
private static boolean isPresent(String data) {
try {
Enum.valueOf(MyEnum.class, data);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
}
java EvalEnum One
One in MyEnum? true
java EvalEnum Zero
Zero in MyEnum? false