Tag Archives: Project summary

OpenFeignClient Use Object to Receive text/plain Type Return Error

report errors

Could not extract response: no suitable HttpMessageConverter found for
response type [classxxxx] and content type [text/plain]

reason

The return type content type is not application/JSON, but text/plain. It cannot be deserialized into object type, as shown in the figure

spring cloud openfeign essentially uses okhttpclient for request. If it is text/plain, it will be treated as text and cannot be deserialized automatically like JSON string, The following is my feinclient:

in this case, it is necessary to do compatibility processing for the return of this content type
add the jackson2httpmessageconverter conversion class, and increase the compatibility of text/plain and text/HTML return types

import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:[email protected]">Tino.Tang</a>
 * @version ${project.version} - 2021/12/9
 */
public class MyJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {

  public LokiJackson2HttpMessageConverter() {
    List<MediaType> mediaTypes = new ArrayList<>();
    mediaTypes.add(MediaType.TEXT_PLAIN);
    mediaTypes.add(MediaType.TEXT_HTML);
    setSupportedMediaTypes(mediaTypes);
  }
}

Add openfeign custom configuration and inject Decoder Bean.

import feign.Logger;
import feign.codec.Decoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author <a href="mailto:[email protected]">Tino.Tang</a>
 * @version ${project.version} - 2021/11/29
 */
@Configuration
public class OpenFeignLogConfig {

  @Bean
  public Logger.Level feignLoggerLeave() {
    return Logger.Level.FULL;
  }

  @Bean
  public Decoder feignDecoder() {
    LokiJackson2HttpMessageConverter converter = new LokiJackson2HttpMessageConverter();
    ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(converter);
    return new SpringDecoder(objectFactory);
  }
}```

After processing, the call to the feign client will no longer report errors, regardless of whether the type is application/json or text/plain, it can be correctly deserialized to Object.

Spring error: ora-01017: invalid username / password; login denied

Today, during the integration of Spring and MyBatis, we conducted tests and found that the SQL query could not connect to the database. The exception log is as follows:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (ORA-01017: invalid username/password; logon denied
)
### The error may exist in com/summerzhou/base/mapper/SysuserMapper.xml
### The error may involve com.summerzhou.base.mapper.SysuserMapper.selectByPrimaryKey
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (ORA-01017: invalid username/password; logon denied
)
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
	at com.sun.proxy.$Proxy3.selectOne(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:163)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:43)
	at com.sun.proxy.$Proxy4.selectByPrimaryKey(Unknown Source)
	at com.summerzhou.test.TestClass.findUserById(TestClass.java:27)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

The user/password is not valid. I have tried Oracle and the password is correct. Then check db.properties to see that the username and password are correct

driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@192.168.25.129:1521:orcl
username=tommy
password=***

Use the Spring Framework to get a DataSource instance. Check the userName of the DataSource and find that the result is X, not Tommy specified in the DB file.

    @Test
    public void setDateSource() {
		BasicDataSource dataSource = (BasicDataSource) applicationContext.getBean("dataSource");
		System.out.println(dataSource.getUsername());
    }

I suddenly realized that x was the username of my native. I looked it up. context:property-placeholder> Is used to activate “${} placeholder, parsing the location attribute defined in the file, generated a accomplished instance, accomplished to externalize based on Java properties format defined properties, and can make the programmer to customize the specific environmental properties, such as a database url and password, so that we can only change the corresponding properties file, without affecting framework.
in my definition of db. The properties, the user name of the key for the username, dataSource injection of attribute value is ${username}, but this username is not the values in the file. Because is accomplished not only in the specified attributes defined in the properties file, also will check the properties in the Java runtime environment. We can customize the order in which the properties are checked by the system-properties-mode property, which has four values:
1) ENVIRONMENT: default property, which is read in the runtime first, or in the properties file specified in the location if the specified property value is not obtained.
2) None: Never check the system properties, only resolve the properties file
) Override: system-local properties
4>allback: properties before system
In conclusion, there are two solutions:
1. The key from the properties file before fully coupled with JDBC., so when reading properties don’t conflict with system properties

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.25.129:1521:orcl
jdbc.username=tommy
jdbc.password=****

DataSource injection changed to:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
	<property name="driverClassName" value="${jdbc.driverClassName}"></property>
	<property name="url" value="${jdbc.url}"></property>
	<property name="username" value="${jdbc.username}"></property>
	<property name="password" value="${jdbc.password}"></property>
</bean>

2. Will & lt; context:property-placeholder> Change the system-properties-mode to None or Fallback