AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-10461625

PatPanda's questions

Martin Hope
PatPanda
Asked: 2025-04-17 05:39:54 +0800 CST

Tenha valor em minúsculas do campo Enum ao enviar solicitação com Spring

  • 5

Gostaria de enviar solicitações http com um valor em minúsculas, onde na variável de caminho, o valor é obtido de um Enum com valores em maiúsculas.

Em um código muito simples:

@HttpExchange(accept = "application/json")
public interface FooHttpExchange {
    
    @GetExchange("/api/1.1/{day}/dosomething")
    String doSomethingWithDayOfWeek(@PathVariable("day") Day day);

com o Enum:

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

Como você pode ver, todos os valores da enumeração estão em letras maiúsculas, para respeitar as convenções Java sobre enumeração.

Mas também obtenho os Enums de bibliotecas de terceiros. Não posso alterar o conteúdo do Enum.

Eu esperaria enviar isso como uma solicitação (tomando segunda-feira como exemplo):

http://example.com/api/1.1/monday/dosomething

Infelizmente, ele está enviando isto:

http://example.com/api/1.1/MONDAY/dosomething

E no lado do servidor, há uma análise, ou seja, ele espera coisas em letras minúsculas.

A solicitação falha

Se eu alterasse a enumeração para letras minúsculas, poderia confirmar que a solicitação estaria funcionando.

E às vezes, obtenho o Enum diretamente de uma biblioteca de terceiros, onde não posso alterar o código.

No entanto, isso quebra a convenção de enumeração do Java que exige que elas sejam colocadas em letras maiúsculas no código.

Como ter a enumeração Java em letras maiúsculas, mas poder enviá-la em letras minúsculas ao enviar a solicitação http?

java
  • 2 respostas
  • 62 Views
Martin Hope
PatPanda
Asked: 2025-04-15 06:04:36 +0800 CST

Página "Coordenadas Maven" do site Maven para indicar também o repositório privado para download

  • 4
  • O que estou tentando alcançar:

Na página do site gerada pelo Maven, em particular na página "Coordenadas Maven", gostaria de adicionar as informações do repositório privado para baixar o artefato.

  • Mostrar algum código:

Aqui está o trecho do meu arquivo pom:

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.21.0</version>
            </plugin>
        </plugins>
    </build>

    <reporting>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>taglist-maven-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <tagListOptions>
                        <tagClasses>
                            <tagClass>
                                <tags>
                                    <tag>
                                        <matchString>todo</matchString>
                                        <matchType>ignoreCase</matchType>
                                    </tag>
                                </tags>
                            </tagClass>
                        </tagClasses>
                    </tagListOptions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>3.9.0</version>
            </plugin>
        </plugins>
    </reporting>

    <distributionManagement>
        <repository>
            <id>private-repository-release</id>
            <url>https://private.repository.com/artifactory/private-repository-release</url>
        </repository>
    </distributionManagement>

Como você pode ver, este jar será implantado em um repositório privado (aqui no meu exemplo https://private.repository.com/artifactory/private-repository-release )

Para responder à pergunta, vamos supor que este repositório privado não precise de autenticação.

  • Descreva os resultados reais:

Ao executar mvn siteo comando acima, obtenho o site maven gerado (funcionando), mas ele se parece com isso (veja a imagem)

insira a descrição da imagem aqui

  • Problema

Esta página não contém informações sobre o repositório privado para download. Gostaria de poder indicar no site o repositório necessário no pom.

  • Descreva os resultados esperados:

Gostaria de obter esse tipo de resultado:

insira a descrição da imagem aqui

Para informar o usuário sobre este jar, o bloco de código do repositório precisa ser adicionado à página do site.

  <repositories>
        <repository>
            <id>private-repository-release</id>
            <url>https://private.repository.com/artifactory/private-repository-release</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>deleteme-kafka</artifactId>
            <version>2.2</version>
        </dependency>
  • Descreva o que tentei:

Tentei adicionar os blocos no pom, mas sem sorte, o site não indica nas "Coordenadas Maven" o repositório privado necessário.

Embora a página "Gerenciamento de distribuição" indique algumas informações sobre o repositório privado, ela não informa ao usuário deste jar como configurar o pom para baixar este "jar privado".

  • Pergunta:

Como adicionar a seção de repositório na página "Coordenadas Maven"?

maven
  • 1 respostas
  • 22 Views
Martin Hope
PatPanda
Asked: 2025-04-06 19:42:36 +0800 CST

Jackson desserializa enum sem distinção entre maiúsculas e minúsculas

  • 5

Gostaria de decodificar valores maiúsculos e minúsculos para um Java Enum em valores simples e em Array.

Eu tentei este pedaço de código:

public enum FooBarEnum {
    FOO,
    BAR
}

os seguintes POJOs para desserializar coisas:

public record Aaa(String something, FooBarEnum foobar)

public record Bbb(String something, List<FooBarEnum> foobarList)

Ao tentar obter o objeto via solicitação HTTP:

@GetExchange("/api/test1")
Aaa getAaa(@PathVariable int key);

Para isso, funciona, não importa se o servidor responde a um objeto com FOO, foo, BAR ou bar, funciona.

No entanto, tenho isto:

@GetExchange("/api/test2")
Bbb getBbb(@PathVariable int key);

Quando estiver em letras minúsculas, encontrarei esta exceção:

JSON decoding error: Cannot deserialize value of type `com.FooBarEnum` from String "foo": not one of the values accepted for Enum class: [FOO, BAR]

[...]
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.FooBarEnum` from String "foo": not one of the values accepted for Enum class: [FOO, BAR]

 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 996] (through reference chain: com.Bbb["fooBarList"]-java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67) ~[jackson-databind-2.18.3.jar:2.18.3]

Eu até tentei adicionar

@JsonFormat(with = {JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_VALUES})

mas sem sorte.

Existe uma maneira de lidar com o caso de ignorar para array também?

java
  • 1 respostas
  • 60 Views
Martin Hope
PatPanda
Asked: 2025-04-03 03:34:16 +0800 CST

mvn deploy:deploy em um jar correto existente resulta em jar corrompido no artifactory

  • 5

Gostaria de fazer upload e implantar um jar existente no artifactory.

Há um pipeline de terceiros, sobre o qual não tenho controle algum, qual etapa 1 construirá um jar. O jar é então colocado em um host, em seu diretório de arquivos. Novamente, não tenho controle sobre o trabalho em si.

Mas eu posso ver quando entro manualmente no host que o jar está correto fazendo jar xf thejar.jar. O conteúdo extraído teria todos os arquivos de classe apropriados.

Agora, minha parte, etapa 2, estou tentando carregar este jar em um artefato.

Entendo que há uma opção para executar mvn deploy, mas isso executaria todas as etapas anteriores do ciclo de vida do maven. Como o jar está correto, gostaria de evitar essa duplicação (executar todas as etapas anteriores do ciclo de vida do maven) e apenas fazer upload do jar.

Até agora, encontrei duas soluções:

  1. parece mvn deploy:deployque esta solução não repete tudo, mas apenas tenta carregar o jar

  2. execute mvn jar:jar deploy:deployo mesmo, parece que esta solução não reexecuta tudo, mas apenas tenta carregar o jar

Entretanto, a solução 1 produziria o seguinte problema:

[INFO] ----------------------< com.example:mavendeploy >-----------------------
[INFO] Building mavendeploy 4.3
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- deploy:3.1.2:deploy (default-cli) @ mavendeploy ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.329 s
[INFO] Finished at: 2025-T19:26:20Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:3.1.2:deploy (default-cli) on project mavendeploy: The packaging plugin for project mavendeploy did not assign a file to the build artifact -> [Help 1]

Parece que nem detecta o jarro.

Enquanto a segunda solução produzirá esse problema.

[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- jar:3.4.1:jar (default-cli) @ mavendeploy ---
[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: /builds/path/to/jar/mavendeploy-4.3.jar
[INFO] 
[INFO] --- deploy:3.1.2:deploy (default-cli) @ mavendeploy ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Embora pareça detectar o jar correto corretamente, há este aviso, JAR will be emptye também, embora o jar pareça estar realmente carregado no artifactory, o jar baixado do artifactory não contém nenhum dos arquivos de classes. Por quê?

Qual é a maneira correta de fazer upload de um jar existente no artifactory usando mvn deploy(espero que sem ter que executar novamente todo o ciclo de vida do maven, já que o jar já está lá)?

O que fiz de errado na solução 1 ou na solução 2?

java
  • 1 respostas
  • 45 Views
Martin Hope
PatPanda
Asked: 2025-02-15 03:17:00 +0800 CST

ArchUnit - regra para verificar se há menos de N arquivos (classes, interfaces, etc...) em um pacote folha

  • 4

O que eu gostaria de conseguir é escrever uma regra ArchUnit para garantir que nossos pacotes permaneçam pequenos o suficiente.

Por exemplo, suponha isto:

natural
 ├─ goodpackage
 │  ├─ apple
 │  ├─ banana
 │  ├─ mango
 ├─ badpackage
 │  ├─ file1
 │  ├─ file2
 │  ├─ ...
 │  ├─ file10

Neste exemplo, digamos que mais de 9 arquivos é muito, enquanto até 8 arquivos é pouco o suficiente.

Isso também é apenas para pacotes leaf, ou seja, os pacotes de nível mais baixo (se houver arquivos neste pacote, mas também subpacotes, o teste deve ter como alvo os subpacotes)

Tentei usar a classe com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classese esperava encontrar uma maneira de iterar dentro de um pacote, mas sem sorte.

Também pesquisei se podemos obter os pacotes diretamente do ArchUnit, algo como:

    @Test
    void leafPackagesShouldNotHaveMoreThan9Files() {   }
        packages().that().areInSubPackages().shouldNot().have(moreThan9Files()).check(importedClasses);
    }

Mas também não é possível.

Como verificar se há menos de N arquivos em um pacote leaf com o ArchUnit?

java
  • 1 respostas
  • 17 Views
Martin Hope
PatPanda
Asked: 2025-02-12 05:08:59 +0800 CST

Alterar Spring Security SecurityFilterChain Bean com base em uma propriedade e não em um perfil

  • 5

Gostaria de configurar o SecurityFilterChain Bean usado com base em uma propriedade configurável.

Temos o mesmo aplicativo, que suporta diferentes tipos de segurança.

@Configuration
@EnableWebSecurity
class SecurityConfiguration {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()).csrf(AbstractHttpConfigurer::disable);
        return httpSecurity.build();
    }

    @Bean
    public SecurityFilterChain securityFilterChainX509(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .x509()
                .subjectPrincipalRegex("CN=(.*?)(?:,|$)");
        return httpSecurity.build();
    }

    @Bean
    public SecurityFilterChain securityFilterChainJWT(HttpSecurity httpSecurity) throws Exception {
        
    }
    
    [...]

}

Estou colando apenas um exemplo aqui, mas imagine que este arquivo está cheio de beans SecurityFilterChain com muitos tipos de autenticação, vamos imaginar 50.

O caso de uso é que cada uma das instâncias do mesmo aplicativo tem sua própria configuração de segurança.

Por exemplo, o aplicativo implantado nos EUA precisa verificar o certificado do cliente, portanto, precisaria usar o bean securityFilterChainX509, enquanto o mesmo aplicativo implantado na França precisaria verificar o nome de usuário e a senha, enquanto o aplicativo implantado no Japão precisaria de outro tipo de autenticação, etc., etc., etc.

Até agora, estamos usando uma abordagem um tanto "estranha", que usamos com base em perfis .

Com isso quero dizer:

    @Bean
    @Profile({"canada", "brazil"})
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()).csrf(AbstractHttpConfigurer::disable);
        return httpSecurity.build();
    }

    @Bean
    @Profile({"usa", "egypt"})
    public SecurityFilterChain securityFilterChainX509(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .x509()
                .subjectPrincipalRegex("CN=(.*?)(?:,|$)");
        return httpSecurity.build();
    }

    @Bean
    @Profile({"germany"})
    public SecurityFilterChain securityFilterChainJWT(HttpSecurity httpSecurity) throws Exception {

    }

Embora essa abordagem esteja funcionando, ela tem desvantagens e exige que:

  • manter muitas propriedades application-profile.properties, apenas para obter o bean correto.
  • quando precisamos mudar (hoje o Brasil usa o inseguro, amanhã precisa do JWT) somos obrigados a mudar o código também.

(Realmente quero evitar perfis se possível)

Pergunta:

Existe uma maneira, sem perfil, mas com uma propriedade configurável, algo como

@Value("${the.security.bean.to.use}")
private String configuredSecurityBeanToUse;

Para configurar o bean SecurityFilterChain a ser usado?

java
  • 1 respostas
  • 38 Views
Martin Hope
PatPanda
Asked: 2025-02-11 16:33:01 +0800 CST

Como criar uma regra ArchUnit para testar se os campos são privados em pacotes

  • 6

Gostaria de criar uma regra ArchUnit que verifica se uma classe não está quebrando o encapsulamento ao expor um campo público.

O único campo público permitido deve ser uma constante, algo comopublic static final int MAX_USERS = 100;

Outros campos não devem ser públicos

Fui tentar o seguinte código:

@Test
void fieldShouldAllBePrivateToProtectEncapsulation() {
    fields().should().bePrivate().check(importedClasses);
}

Infelizmente isso não funciona.

Por exemplo, ele está sinalizando esta classe como ruim:

enum Device {
    IOS,
    LAPTOP

Como posso escrever um teste no ArchUnit para garantir que nenhum campo seja público, exceto constante?

java
  • 1 respostas
  • 27 Views
Martin Hope
PatPanda
Asked: 2025-02-11 03:32:51 +0800 CST

Como posso excluir uma regra ArchUnit que visa a interface para impactar @interface (anotação)

  • 4

Gostaria de escrever um teste ArchUnit que diz:

"as classes que são interfaces devem ter um nome terminado com Interface, mas não as @interfaceque são (são anotações)".

Por exemplo, isto deve estar OK:

// Interface definition
interface AnimalInterface {
void animalSound(); // abstract method
void sleep(); // abstract method
}

Mas isso não deveria

// Interface definition
interface Animal {
void animalSound(); // abstract method
void sleep(); // abstract method
}

Mas também (e é nessa parte que estou tendo problemas):

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = SomethingValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidSomething {
    String message() default "Invalid request data";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Não deve ser levado em consideração neste teste, pois @interfacenão é interface.

Tentei fazer isso escrevendo o seguinte código:

@Test
void interfacesShouldHaveNamesEndingWithTheWordInterface() {
    classes().that().areInterfaces().should().haveNameMatching(".*Interface").check(importedClasses);
}

Mas isso não daria certo @interface.

Como melhorar o teste para "ignorar" e "filtrar" anotações?

java
  • 1 respostas
  • 30 Views
Martin Hope
PatPanda
Asked: 2025-02-04 22:58:05 +0800 CST

SpringBoot @Valid em um campo, com base no valor de outro campo

  • 6

Gostaria de usar o SpringBoot @Valid para validar um campo de solicitação http, mas com base em outro campo da mesma solicitação http.

Tenho o seguinte código:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <artifactId>question</artifactId>

    <properties>
        <maven.compiler.source>23</maven.compiler.source>
        <maven.compiler.target>23</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

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

@SpringBootApplication
class FieldValidationApplication {

    public static void main(String[] args) {
        SpringApplication.run(FieldValidationApplication.class, args);
    }

}
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
class FieldValidationController {

    @PostMapping("/validate")
    String question(@Valid @RequestBody SomeRequest someRequest) {
        return "please validate the field";
    }

}

record SomeRequest(int score,
                   String fieldPositive,
                   String fieldZeroAndNegative
                   ) 
{ }

As regras de validação são bastante simples:

O payload da requisição tem um field score. Se o valor do field score for estritamente positivo, então preciso verificar se o campo fieldPositive é uma string válida e também se fieldZeroAndNegative é nulo.

Por exemplo:

{
  "score": 1,
  "fieldPositive": "thisisok"
}

Mas estes não são:

{
  "score": 1
}

{
  "score": 1,
  "fieldPositive": ""
}

{
  "score": 1,
  "fieldPositive": "below fieldZeroAndNegative should be null",
  "fieldZeroAndNegative": "not ok"
}

Regra semelhante para o outro campo (código logo abaixo).

Foi isso que tentei, criei uma anotação personalizada:

record SomeRequest(int score,
                   @ValidateThisFieldOnlyIfScoreIsPositive String fieldPositive,
                   @ValidateThisFieldOnlyIfScoreIsZeroOrNegative String fieldZeroAndNegative
                   ) 
{ }

import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = ValidateThisFieldOnlyIfScoreIsPositiveValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface ValidateThisFieldOnlyIfScoreIsPositive
{
    String message() default "Field is invalid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}


import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

class ValidateThisFieldOnlyIfScoreIsPositiveValidator implements ConstraintValidator<ValidateThisFieldOnlyIfScoreIsPositive, String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        System.out.println("hello, the value of the field fieldPositive is " + value);
        System.out.println("However, I cannot get the value of the field score");
        if (" SomeRequest score " > 0) { //how to get the value of the field score here?
            return value != null && !value.isEmpty() && value.length() > 3;
        }
        if (" SomeRequest score"  <= 0) {
            return value == null;
        }
        ...
    }

}

import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = ValidateThisFieldOnlyIfScoreIsZeroOrNegativeValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface ValidateThisFieldOnlyIfScoreIsZeroOrNegative
{
    String message() default "Field is invalid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

class ValidateThisFieldOnlyIfScoreIsZeroOrNegativeValidator implements ConstraintValidator<ValidateThisFieldOnlyIfScoreIsZeroOrNegative, String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        System.out.println("hello, the value of the field fieldZeroAndNegative is " + value);
        System.out.println("However, I cannot get the value of the field score");
        if (" SomeRequest score " <= 0) { //how to get the value of the field score here?
            return value != null && !value.isEmpty() && value.length() > 3;
        }
        if (" SomeRequest score" > 0) {
            return value == null;
        }

    }

}

Não tenho certeza se usar uma anotação por campo é a melhor opção para começar.

Pergunta:

Como obter ambos os campos (ou vários campos) da mesma solicitação no validador?

java
  • 1 respostas
  • 49 Views
Martin Hope
PatPanda
Asked: 2025-01-14 05:59:10 +0800 CST

use spring-boot-starter-oauth2-client para passar o token para o Spring Framework release 6 HttpInterface @HttpExchange @GetExchange

  • 5

Estou tentando usar spring-boot-starter-oauth2-client com o novo Spring Framework release 6 HttpInterface

@Configuration
public class RestClientConfig {

    @Bean
    public RestClient restClient(OAuth2AuthorizedClientManager authorizedClientManager, RestClient.Builder restClientBuilder) {
        OAuth2ClientHttpRequestInterceptor interceptor = new OAuth2ClientHttpRequestInterceptor(authorizedClientManager);
        return restClientBuilder
                .requestInterceptor(interceptor)
                .build();
    }

}
@RestController
public class LessonsController {

    private final RestClient restClient;

    public LessonsController(RestClient restClient) {
        this.restClient = restClient;
    }

    @GetMapping("/lessons")
    public String fetchLessons() {
        return restClient.get()
                .uri("https://someserver.om/someprotectedresource")
                .attributes(clientRegistrationId("my-client"))
                .retrieve()
                .body(String.class);
    }
}
spring:
  application:
    name: client-application
  security:
    oauth2:
      client:
        registration:
          my-client:
            provider: my-provider
            client-id: ididid
            client-secret: secretsecret
            authorization-grant-type: client_credentials
            scope: download
        provider:
          my-provider:
            token-uri: https://provider.com/token

O acima está funcionando. Temos a confirmação do provedor de token de que obtivemos o token, assim como do servidor de recursos de que obtivemos o recurso, passando o token. Ambas as duas etapas estão funcionando bem, feliz.

https://www.youtube.com/watch?v=aR580OCEp7w Agora gostaríamos de fazer o mesmo, com a nova versão 6 do Spring Framework HttpInterface

Ao fazer isso:

@Configuration
public class UserClientConfig {

    private final RestClient restClient;

    public UserClientConfig(OAuth2AuthorizedClientManager authorizedClientManager, RestClient.Builder restClientBuilder) {
        OAuth2ClientHttpRequestInterceptor interceptor = new OAuth2ClientHttpRequestInterceptor(authorizedClientManager);
        this.restClient = restClientBuilder
                .requestInterceptor(interceptor)
                .baseUrl("https://host.com")
                .build();
    }

    @Bean
    public UserClient userClient() {
        RestClientAdapter adapter = RestClientAdapter.create(restClient);
        return HttpServiceProxyFactory.builderFor(adapter)
                .build()
                .createClient(UserClient.class);
    }

}
@HttpExchange(
        url = "/v1",
        accept = MediaType.APPLICATION_JSON_VALUE)
public interface UserClient {

    @GetExchange("/protectedresource/full")
    public User getUserById(@RequestParam Map<String, String> key value);

}
    @GetMapping("/lessons")
    public User fetchLessons() {
        return userClient.getUserById(Map.of("foo", "bar"));
    }

Ao usar HttpInterface, isso não funcionaria. O token não é buscado em primeiro lugar. Talvez por causa da falta de .attributes(clientRegistrationId("id")) para @HttpExchange @GetExchange, mas não tenho certeza.

Pergunta: como combinar a interface HTTP com o token spring-boot-starter-oauth2-client?

spring-boot
  • 1 respostas
  • 45 Views
Martin Hope
PatPanda
Asked: 2025-01-09 01:33:12 +0800 CST

Problema ao enviar grant_type com spring-boot-starter-oauth2-client e RestClient

  • 4

Estou tentando usar spring-boot-starter-oauth2-clientpara obter um token portador, onde o serviço está aceitando grant_type=client_credentialse não authorization-grant-type.

curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -u theusername:thepassword  "https://thirdpartyservice.com/token?scope=resolve+download&grant_type=client_credentials" | jq -r '.access_token'

Isso funcionaria, se pudéssemos obter o token.

Seguindo a documentação sobre Spring Security, estou configurando:

spring:
  application:
    name: client-application
  security:
    oauth2:
      client:
        registration:
          my-client:
            provider: the-provider
            client-id: theusername
            client-secret: thepassword
            authorization-grant-type: client_credentials
            #grant_type: client_credentials
            scope: resolve+download
        provider:
          the-provider:
            token-uri: https://thirdpartyservice.com/token
logging:
  level:
    root: DEBUG
@Configuration
public class RestClientConfig {

    @Bean
    public RestClient restClient(OAuth2AuthorizedClientManager authorizedClientManager) {
        OAuth2ClientHttpRequestInterceptor interceptor = new OAuth2ClientHttpRequestInterceptor(authorizedClientManager);
        return RestClient.builder()
                .requestInterceptor(interceptor)
                .build();
    }

}
return restClient.get()
                .uri("https://resource...")
                .attributes(clientRegistrationId("my-client"))
                .retrieve()
                .body(String.class);

Infelizmente, isso não está funcionando. O provedor de token retorna o erro 400, como esperado grant_type(tipo de concessão de sublinhado).

Mas parece que o Spring Security oferece apenas "autorização-concessão-tipo"

Como passar grant_typeusando RestCliente spring-boot-starter-oauth2-client?

java
  • 1 respostas
  • 37 Views
Martin Hope
PatPanda
Asked: 2024-12-06 06:08:03 +0800 CST

IntelliJ - Traga o mvn clean install para um botão

  • 5

Estou desenvolvendo projetos Java Maven usando IntelliJ.

Para compilar o projeto com suas dependências, utilizo muitomvn clean install

Toda vez, acabo clicando na IU neste ícone e, em seguida, clicando em recarregar (veja a captura de tela)

Tentei atribuir essa ação a um botão no teclado ou no mouse.

No entanto, não consegui descobrir qual ação é essa.

O mais próximo que consegui encontrar foi a vinculação "Executar configuração", no entanto, isso não leva em consideração tudo (todos os passos da captura de tela)

insira a descrição da imagem aqui

Pergunta:

Como vincular mvn clean installa um botão?

maven
  • 1 respostas
  • 20 Views
Martin Hope
PatPanda
Asked: 2024-12-03 06:23:08 +0800 CST

Qual é o propósito da classe SpringBoot Enum WebApplicationType

  • 5

Existe um documento oficial da Spring sobre WebApplicationType

https://docs.spring.io/spring-boot/api/java/org/springframework/boot/WebApplicationType.html

A camada de aplicação pode escolher definir:

NONE
The application should not run as a web application and should not start an embedded web server.
REACTIVE
The application should run as a reactive web application and should start an embedded reactive web server.
SERVLET
The application should run as a servlet-based web application and should start an embedded servlet web server.

Eu inadvertidamente esqueci de definir spring.main.web-application-type=reactivemeu aplicativo Spring Webflux.

Eu também esqueci inadvertidamente de definir spring.main.web-application-type=servletmeu aplicativo Spring MVC.

No entanto, ambos conseguiram atender às solicitações, o aplicativo estava instalado e funcionando, e tudo parecia bem.

Portanto, tenho uma pergunta, qual é o propósito deste WebApplicationType? Parece que ele não está fazendo nada

spring
  • 1 respostas
  • 27 Views
Martin Hope
PatPanda
Asked: 2024-11-05 05:34:11 +0800 CST

Como usar a API KafkaSender do Reactor Kafka para enviar mensagens para dois tópicos diferentes (situados em dois clusters Kafka diferentes)?

  • 5

Estou tentando enviar mensagens para dois tópicos diferentes do Kafka usando o KafkaSender do Reactor Kafka.

Por dois tópicos diferentes do Kafka, quero dizer: Há um tópico chamado "first_topic" no cluster kafka-first-broker.com:9092 Então, há outro tópico chamado "another_topic", em outro cluster, não o mesmo que o acima, chamado kafka-another-broker-not-the-same-as-above.com:9093

No entanto, parece que o sendmétodo do reator Kafka suporta apenas um destino

Tentei usar o método send com uma lista separada por vírgulas de (dois tópicos)

SenderRecord.create(new ProducerRecord<>("first_topic,another_topic", null, mymessage), mymessage)

Eu esperava que isso fosse enviado para dois tópicos diferentes, mas só pode ser enviado para um.

Como posso aproveitar a API KafkaSender do Reactor Kafka para enviar mensagens para dois tópicos diferentes situados em dois clusters Kafka diferentes?

java
  • 1 respostas
  • 16 Views
Martin Hope
PatPanda
Asked: 2024-07-15 17:30:56 +0800 CST

Problema de refatoração if-else-if string.contains("X") para alternar entre maiúsculas e minúsculas (ou melhor)

  • 4
  • Inclua detalhes sobre seu objetivo:

Gostaria de refatorar if-else-if string.contains("X")instruções em java para mudar de caso ou mapa.

  • Mostre algum código:

Eu tenho um trecho de código, muito simples, que se parece com:

     public String question(String sentence) {
        if (sentence.contains("eat")) {
            return getFoodFromSentence(sentence);
        } else if (sentence.contains("drink")) {
            return getBeverageFromSentence(sentence);
        } else if (sentence.contains("drive")) {
            return getVehicleFromSentence(sentence);
        } else if (sentence.contains("travel")) {
            return getDestinationFromSentence(sentence);
    [...
        many many other else if
    ...]
        } else {
            return "sentence with unknown verb";
        }
    }

    private String getDestinationFromSentence(String sentence) {
        return ""; //some complex code to extract some info from the sentence
    }

    private String getVehicleFromSentence(String sentence) {
        return ""; //some complex code to extract some info from the sentence
    }
[... all the other actual handling methods ]

Desejo refatorar isso usando um switch case:

  • Descreva o que tentei:

Usando caixa de comutação:

   public String question(String sentence) {
        switch (???) { //issue here, I am not able to come up with the expression
            case (sentence.contains("eat")): // issue here, I am not able to have the cases representing the if
                return getFoodFromSentence(sentence);
            case (sentence.contains("drink")):
                return getBeverageFromSentence(sentence);
            case (sentence.contains("drive")):
                return getVehicleFromSentence(sentence);
            case (sentence.contains("travel")):
                return getDestinationFromSentence(sentence);
        [ ... the other case conditions ... ]
            default:
                return "sentence with unknown verb";
        }
    }

Também tentei usar o padrão Map, algo como:

 public String question(String sentence) {
        Map<Predicate<String>, Function<String, String>> map =
                Map.of(s -> s.contains("eat"), s -> getFoodFromSentence(s),
                        s -> s.contains("drink"), s -> getBeverageFromSentence(s),
                        s -> s.contains("drive"), s -> getVehicleFromSentence(s),
                        s -> s.contains("travel"), s -> getDestinationFromSentence(s));
        return map.get(???).apply(sentence); // issue here, how to get the correct key of the map?
    }
  • Pergunta:

Posso perguntar como resolver os problemas de uso do switch case?

Ou talvez como resolver o Mapa?

Existe outra técnica para refatorar isso if-else-if string.contains("X")?

java
  • 3 respostas
  • 85 Views
Martin Hope
PatPanda
Asked: 2024-04-12 08:10:53 +0800 CST

Como fazer com que um jobB do stageB seja executado somente quando TODOS os jobs do stageA forem concluídos

  • 5
  • Inclua detalhes sobre seu objetivo:

Eu gostaria que um jobB do stageB fosse executado somente quando TODOS os jobs do stageA fossem concluídos.

stageA  stageB
job01A  jobB
job02A
...
job58A
  • O que eu tentei:

Para alcançar esse resultado, estou usando atualmente a palavra-chave "needs", que está funcionando, mas o gitlab ci yml agora está assim:

jobB
  stage: stageB
  needs:
    - job: job01A
    - job: job02A
       ...
    - job: job58A

Esta lista ou a matriz são longas.

  • Pergunta:

Como posso escrever algo que diga ao jobB para ser executado somente quando todos os trabalhos do estágio A estiverem concluídos, sem ter que escrever explicitamente cada um dos trabalhos? Algo como:

jobB
  stage: stageB
  needs:
    - all jobs from stageA
  • 1 respostas
  • 13 Views
Martin Hope
PatPanda
Asked: 2023-12-20 22:17:05 +0800 CST

Crie um painel do Loki para contagem de registros

  • 5

Estou tentando construir um painel Grafana representando o número de logs de informações no Loki (não no Prometheus). Basicamente, eu gostaria de conseguir isso:

insira a descrição da imagem aqui

Pesquisei e parece que é possível construir aqueles com métricas do Prometheus, usando as logback_eventsmétricas do Prometheus.

Na verdade, o painel acima está usando dados do Prometheus, logback_eventsnão dos dados do Loki.

Porém meu aplicativo não está enviando nenhuma métrica, apenas logs para o Loki. Portanto, não posso confiar em métricas desse tipo logback_eventspara construir este painel.

Onde um log de amostra se parece com:

{
"name": "mycoolapp"
"pid": "1",
"level": "INFO",
"thread": "somethread",
"class": "SomeClass",
"traceId": "6170ea9877f59d050a13feaffc145d88"
"spanId": "6729eec142171c8f"
"message": "somecoolmessage"
}

Existe uma maneira de obter o número de logs de informações, erros, avisos e depuração do Loki? Como construir um painel semelhante usando dados do Loki (não do Prometheus)?

grafana
  • 1 respostas
  • 55 Views
Martin Hope
PatPanda
Asked: 2023-12-12 00:12:29 +0800 CST

aviso: não @param para campo em java 21 com javadoc

  • 6
  • O que estou tentando alcançar:

Gere javadoc para registros java 21 muito simples.

  • O que eu tentei:

Eu tenho este registro simples:

/**
 * The type Some record.
 */
public record SomeRecord(String someField) {
}

e este pom:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <configuration>
        <outputDirectory>target/javadoc</outputDirectory>
        <reportOutputDirectory>target/javadoc</reportOutputDirectory>
        <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
    </configuration>
</plugin>

E estou executando este comando maven:

mvn clean install site -U javadoc:javadoc
  • Emitir:

Reproduzível 100%, entendo o seguinte:

SomeRecord.java:6: warning: no @param for someField
[WARNING] public record SomeRecord(String someField) {
[WARNING] ^
  • Pergunta:

O que está errado neste código? O que é isso @param? Lembro-me de um @Param para Spring, mas @param (minúsculas?) Como posso gerar sem o javadoc corretamente?

java
  • 1 respostas
  • 30 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve