My custom dialect with processor doesn't parse any value and I don't know why. In generated view there is nothing in place where ${content} should be and after changing tag to th:text it appears. I'm using Spring Boot v1.5.9.RELEASE, Spring v4.3.13.RELEASE
pom.xml dependencies (it's submodule)
<properties>
<h2.version>1.4.194</h2.version>
<java-version>1.8</java-version>
<org.thymeleaf-version>3.0.9.RELEASE</org.thymeleaf-version>
<org.thymeleaf.extras-version>3.0.0.RELEASE</org.thymeleaf.extras-version>
<thymeleaf-layout-dialect.version>2.1.2</thymeleaf-layout-dialect.version>
</properties>
<dependencies>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${org.thymeleaf-version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${org.thymeleaf-version}</version>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>${thymeleaf-layout-dialect.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>${org.thymeleaf.extras-version}</version>
</dependency>
<!--WebJars-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!--database-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
LineSeparatorProcessor.java
public class LineSeparatorProcessor extends AbstractAttributeTagProcessor {
private static final String ATTR_NAME = "lstext";
private static final int PRECEDENCE = 10000;
public LineSeparatorProcessor(final String dialectPrefix) {
super(
TemplateMode.HTML,
dialectPrefix,
null,
false,
ATTR_NAME,
true,
PRECEDENCE,
true);
}
protected void doProcess(
final ITemplateContext context, final IProcessableElementTag tag,
final AttributeName attributeName, final String attributeValue,
final IElementTagStructureHandler structureHandler) {
final IEngineConfiguration configuration = context.getConfiguration();
final IStandardExpressionParser parser =
StandardExpressions.getExpressionParser(configuration);
final IStandardExpression expression = parser.parseExpression(context, attributeValue);
final String value = (String) expression.execute(context);
structureHandler.setBody(
HtmlEscape.escapeHtml5Xml(value).replace(System.getProperty("line.separator"), "<br />"),
false);
}
}
MyDialect.java
public class MyDialect extends AbstractProcessorDialect {
public MyDialect() {
super(
"MyDialect",
"mydialect",
13000);
}
public Set<IProcessor> getProcessors(final String dialectPrefix){
final Set<IProcessor> processors = new HashSet<>();
processors.add( new LineSeparatorProcessor(dialectPrefix) );
return processors;
}
}
ThymeleafConfiguration.java
#Configuration
public class ThymleafConfiguration {
#Bean
public MyDialect myDialect() {
return new MyDialect();
}
}
view.html
<span mydialect:lstext="${content}" ></span>
You need to add the dialect to the instance of the TemplateEngine. For example:
#Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setEnableSpringELCompiler(true);
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new MyDialect());
return templateEngine;
}
You can find this documented in the Say Hello! Extending Thymeleaf in 5 minutes guide.
Related
I have a spring-boot project with spring-cloud gateway. When I make a http request, I am getting this error. I have been working on trying to solve this issue for days, but I could not manage to solve it.
java.lang.ClassCastException: class org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to class org.springframework.core.io.buffer.NettyDataBufferFactory (org.springframework.core.io.buffer.DefaultDataBufferFactory and org.springframework.core.io.buffer.NettyDataBufferFactory are in unnamed module of loader 'app')
These are versions which I am using for the apllication.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
This is my pom.xml for the service.
<properties>
<!-- Spring -->
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
This is how I am modifying gateway filter.
#Slf4j
public class ModifyHttpMethodGatewayFilter extends
AbstractGatewayFilterFactory<ModifyHttpMethodGatewayFilter.Config> {
public ModifyHttpMethodGatewayFilter() {
super(ModifyHttpMethodGatewayFilter.Config.class);
}
#Override
public GatewayFilter apply(ModifyHttpMethodGatewayFilter.Config config) {
return (exchange, chain) -> {
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
builder.method(config.getMethod());
ServerHttpRequest request = builder.build();
if (!config.getMethod().equals(HttpMethod.GET)) {
// Create request body if missing from a GET request
String bodyString = getRequestBody(request);
DataBuffer bodyDataBuffer = stringDataBuffer(bodyString);
HttpHeaders headers = request.getHeaders();
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
request = new ServerHttpRequestDecorator(request) {
#Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
}
#Override
public HttpHeaders getHeaders() {
return headers;
}
};
}
return chain.filter(exchange.mutate().request(request).build());
};
}
public static class Config {
#NotEmpty
protected HttpMethod method;
public HttpMethod getMethod() {
return method;
}
public Config setMethod(HttpMethod method) {
this.method = method;
return this;
}
}
}
stringDataBuffer method.
public static DataBuffer stringDataBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}
I am building an application with spring boot(war) and primefaces. I created a login with a custom authentication provider. When my app is processing the credentials, spring verify them twice. Why?
ColombianApplication.java
#Configuration
#EnableJpaRepositories("com.colombian.online.repository")
#EntityScan("com.colombian.online.entity")
#ComponentScan("com.colombian.online")
#SpringBootApplication
public class ColombianApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ColombianApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ColombianApplication.class);
}
}
CustomAutheticationProvider.java
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Autowired
private LoginService loginService;
#Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
Usuario usuario = getCurrentUser();
if (usuario == null) {
String username = auth.getName();
String password = auth.getCredentials().toString();
Usuario usuarioQuery = loginService.findUserByCredentials(username, password);
if (usuarioQuery == null) {
throw new UsernameNotFoundException("User not exist or your credentials are incorrect");
}
return new UsernamePasswordAuthenticationToken(usuarioQuery, password);
}
return new UsernamePasswordAuthenticationToken(usuario
, usuario.getPwd());
}
#Override
public boolean supports(Class<?> type) {
return type.equals(UsernamePasswordAuthenticationToken.class);
}
public Usuario getCurrentUser() {
if (SecurityContextHolder.getContext().getAuthentication() != null) {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof String) {
return null;
}
return (Usuario) principal;
} else {
return null;
}
}
}
CustomContextInitializer.java
#Configuration
public class CustomContextInitializer {
#Bean
public ServletContextInitializer servletContextInitializer() {
return servletContext -> {
servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
servletContext.setInitParameter("primefaces.THEME", "nova-light");
};
}
#Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean registration = new ServletRegistrationBean<>(new FacesServlet(), "*.xhtml");
registration.setName("Faces Servlet");
registration.setLoadOnStartup(1);
return registration;
}
#Bean
public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
return new ServletListenerRegistrationBean<>(new ConfigureListener());
}
}
SecurityConfiguration.java
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/resources/**", "/javax.faces.resource/**", "/"
).permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/").failureUrl("/?error=true")
.defaultSuccessUrl("/home")
.and()
.logout().logoutUrl("/logout").permitAll().logoutSuccessUrl("/");
}
#Bean
public FilterRegistrationBean rewriteFilter() {
FilterRegistrationBean rwFilter = new FilterRegistrationBean(new RewriteFilter());
rwFilter.setDispatcherTypes(EnumSet.of(DispatcherType.FORWARD, DispatcherType.REQUEST,
DispatcherType.ASYNC, DispatcherType.ERROR));
rwFilter.addUrlPatterns("/*");
return rwFilter;
}
}
My pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Primefaces with spring -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>7.0</version>
</dependency>
<!--dependency>
<groupId>org.joinfaces</groupId>
<artifactId>joinfaces-dependencies</artifactId>
<version>4.1.1</version>
<type>pom</type>
</dependency-->
<!-- Pretty faces -->
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-servlet</artifactId>
<version>3.4.4.Final</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Loggers -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- Spring tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.1-b04</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.1-b04</version>
<type>jar</type>
</dependency>
</dependencies>
The project has not web.xml. I use ocp library.
I fixed the problem, verifying the current user from SecurityContextHolder, and sending the same credentials.
All of a sudden I receive this message when I try to deploy my Vertx application:
GRAVE: Unhandled exception java.lang.NoSuchMethodError:
'void io.vertx.sqlclient.impl.SocketConnectionBase.(io.vertx.core.impl.NetSocketInternal,
boolean, int, int, int, io.vertx.core.Context)' at
io.vertx.mysqlclient.impl.MySQLSocketConnection.(MySQLSocketConnection.java:46)
at
io.vertx.mysqlclient.impl.MySQLConnectionFactory.lambda$connect$0(MySQLConnectionFactory.java:115)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:131)
Here's the dependencies of my pom file:
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>4.0.0-milestone3</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
<version>4.0.0-milestone3</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-templ-freemarker</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
And this is the code that deploys the HTTP server and the database:
#Override
public void start(Promise<Void> promise) throws Exception {
// Deploy the database
Promise<String> dbVerticleDeployment = Promise.promise();
vertx.deployVerticle(new DatabaseVerticle(), dbVerticleDeployment);
// When the database has been deployed, proceed with the server
dbVerticleDeployment.future().compose(s -> {
// Deploy the HTTPS server
Promise<String> httpVerticleDeployment = Promise.promise();
vertx.deployVerticle(new HttpsServerVerticle(), httpVerticleDeployment);
// Return the future to notify the completion
return httpVerticleDeployment.future();
}).setHandler(stringAsyncResult -> {
// Error handling
if (stringAsyncResult.succeeded())
promise.complete();
else
promise.fail(stringAsyncResult.cause());
});
}
I don't think that the error is on the code but it's something related to maven imports. I probably have messed up versions?
Here's the database
package com.rosanna.mkscoreboards.database;
import com.rosanna.mkscoreboards.database.service.DatabaseService;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.serviceproxy.ServiceBinder;
import io.vertx.sqlclient.PoolOptions;
import java.util.HashMap;
public class DatabaseVerticle extends AbstractVerticle {
// Database connection constants
private static final String HOST_NAME = "localhost";
private static final String DATABASE_NAME = "mkscoreboards";
private static final String DB_USERNAME = "root";
private static final String DB_PASSWORD = "temp_pass";
private static final int MAX_POOL_SIZE = 20;
// Queries
private static HashMap<SqlQuery, String> queries = new HashMap<>();
// Event but identifier
public static final String MKSCOREBOARDS_QUEUE = "mkscoreboards.queue";
#Override
public void start(Promise<Void> promise) throws Exception {
// Connection setup
var connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost(HOST_NAME)
.setDatabase(DATABASE_NAME)
.setUser(DB_USERNAME)
.setPassword(DB_PASSWORD);
var poolOptions = new PoolOptions().setMaxSize(MAX_POOL_SIZE);
// Load the queries
initQueries();
// Create the pooled client
var client = MySQLPool.pool(vertx, connectOptions, poolOptions);
DatabaseService.create(client, queries, ready -> {
if (ready.succeeded()) {
var binder = new ServiceBinder(vertx);
binder.setAddress(MKSCOREBOARDS_QUEUE).register(DatabaseService.class, ready.result());
promise.complete();
} else {
promise.fail(ready.cause());
}
});
}
private void initQueries() {
if (queries.size() == 0) {
queries.put(
SqlQuery.LIST_AVAILABLE_GAMES,
"SELECT * FROM games;"
);
}
}
}
Here's the database service, taken from "Gentle guide to Vertx application"
#ProxyGen
#VertxGen
public interface DatabaseService {
#GenIgnore
static DatabaseService create(MySQLPool dbClient, HashMap<SqlQuery, String> sqlQueries, Handler<AsyncResult<DatabaseService>> readyHandler) {
return new DatabaseServiceImpl(sqlQueries, dbClient, readyHandler);
}
#GenIgnore
static DatabaseService createProxy(Vertx vertx, String address) {
return new DatabaseServiceVertxEBProxy(vertx, address);
}
#Fluent
DatabaseService listAllGames(Handler<AsyncResult<JsonArray>> resultHandler);
}
and
public class DatabaseServiceImpl implements DatabaseService {
private final HashMap<SqlQuery, String> sqlQueries;
private final MySQLPool client;
public DatabaseServiceImpl(HashMap<SqlQuery, String> sqlQueries, MySQLPool client, Handler<AsyncResult<DatabaseService>> readyHandler) {
this.sqlQueries = sqlQueries;
this.client = client;
client.getConnection(result -> {
if (result.failed()) {
readyHandler.handle(Future.failedFuture(result.cause()));
} else {
readyHandler.handle(Future.succeededFuture(this));
}
});
}
#Override
public DatabaseService listAllGames(Handler<AsyncResult<JsonArray>> resultHandler) {
//TODO
return null;
}
}
I have ended up with the fact that this error is related to a bug in vert.x; I have now this error:
java.lang.NoClassDefFoundError: io/vertx/core/impl/NetSocketInternal
at
io.vertx.mysqlclient.impl.MySQLConnectionFactory.lambda$connect$0(MySQLConnectionFactory.java:114)
And the pom is now the following (compare it with the pom in the question for comparing).
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-templ-freemarker</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
There must be issues with vertx itself because all versions are the same, I am using vertx 4
use
<!-- https://mvnrepository.com/artifact/io.vertx/vertx-mysql-client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
<version>4.1.2</version>
</dependency>
or the latest
can you check that the various versions of the vertx components you are using are the same ?
I have a basic SpringBoot 2.1.5.RELEASE app. Using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file with some RestControllers.
In 1 of the controller this is the body I send:
{
"depositHotel": "xxx",
"destinationHotel": "aaa",
"depositHotelAmount": "0.2",
"destinationHotelAmount": "4",
"destinationAddress": [{
"address": "asdf",
"tag": ""
}],
"refundAddress": [{
"address": "pio",
"tag": ""
}]
}
so I create this class to send it as a RequestBody:
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"address",
"tag"
})
public class Address {
public Address() {
super();
}
public Address(String address) {
super();
this.address = address;
}
#JsonProperty("address")
private String address;
#JsonProperty("tag")
private Object tag;
#JsonProperty("address")
public String getAddress() {
return address;
}
#JsonProperty("address")
public void setAddress(String address) {
this.address = address;
}
#JsonProperty("tag")
public Object getTag() {
return tag;
}
#JsonProperty("tag")
public void setTag(Object tag) {
this.tag = tag;
}
}
and
public class HotelswitchHotelOrderRequestBody {
public static class Builder {
private String depositHotel;
private String destinationHotel;
private Float depositHotelAmount;
private Float destinationHotelAmount;
private Address destinationAddress;
private Address refundAddress;
public Builder(String depositHotel, String destinationHotel) {
this.depositHotel = depositHotel;
this.destinationHotel = destinationHotel;
}
public Builder withDepositHotelAmount (Float depositHotelAmount) {
this.depositHotelAmount = depositHotelAmount;
return this;
}
public Builder withDestinationHotelAmount (Float destinationHotelAmount) {
this.destinationHotelAmount = destinationHotelAmount;
return this;
}
public Builder toDestinationAddress (Address destinationAddress) {
this.destinationAddress = destinationAddress;
return this;
}
public Builder toRefundAddress (Address refundAddress) {
this.refundAddress = refundAddress;
return this;
}
public HotelswitchHotelOrderRequestBody build(){
HotelswitchHotelOrderRequestBody order = new HotelswitchHotelOrderRequestBody();
order.depositHotel = this.depositHotel;
order.depositHotelAmount = this.depositHotelAmount;
order.destinationAddress = this.destinationAddress;
order.destinationHotel = this.destinationHotel;
order.destinationHotelAmount = this.destinationHotelAmount;
order.refundAddress = this.refundAddress;
return order;
}
}
private String depositHotel;
private String destinationHotel;
private Float depositHotelAmount;
private Float destinationHotelAmount;
private Address destinationAddress;
private Address refundAddress;
private HotelswitchHotelOrderRequestBody () {
//Constructor is now private.
}
public String getDepositHotel() {
return depositHotel;
}
public void setDepositHotel(String depositHotel) {
this.depositHotel = depositHotel;
}
public String getDestinationHotel() {
return destinationHotel;
}
public void setDestinationHotel(String destinationHotel) {
this.destinationHotel = destinationHotel;
}
public Float getDepositHotelAmount() {
return depositHotelAmount;
}
public void setDepositHotelAmount(Float depositHotelAmount) {
this.depositHotelAmount = depositHotelAmount;
}
public Float getDestinationHotelAmount() {
return destinationHotelAmount;
}
public void setDestinationHotelAmount(Float destinationHotelAmount) {
this.destinationHotelAmount = destinationHotelAmount;
}
public Address getDestinationAddress() {
return destinationAddress;
}
public void setDestinationAddress(Address destinationAddress) {
this.destinationAddress = destinationAddress;
}
public Address getRefundAddress() {
return refundAddress;
}
public void setRefundAddress(Address refundAddress) {
this.refundAddress = refundAddress;
}
}
and
public test postOrder ( HotelswitchHotelOrderRequestBody order) {
HttpEntity<String> entity = new HttpEntity<String>(new JSONObject(order).toString(), headers());
ResponseEntity<OrderResponse> response = new RestTemplate()
.exchange(URL,
HttpMethod.POST, entity, new ParameterizedTypeReference<OrderResponse>() {});
return response.getBody();
}
But i have this error:
java.lang.NoSuchMethodError: org.json.JSONObject.<init>(Ljava/lang/Object;)V
at io.bonanza.backend.service.Hotelswitch.HotelswitchHotelService.postOrder(HotelswitchHotelService.java:132)
at io.bonanza.backend.service.Hotelswitch.HotelswitchHotelServiceTests.testPostOrder(HotelswitchHotelServiceTests.java:151)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.googlecode.libphonenumber</groupId>
<artifactId>libphonenumber</artifactId>
<version>8.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Spring Security -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-test -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<!-- <version>4.5.4</version> -->
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<!-- Firebase dependencies -->
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-firestore</artifactId>
<version>0.26.0-beta</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
</dependencies>
It looks like you have more than one org.json:json dependency on your classpath.
Looking at it:
org.springframework.boot:spring-boot-starter-test depends on
com.jayway.jsonpath:json-path which in turn brings
org.json:json which is may be newer/older than the version on which
io.jsonwebtoken jjwt 0.9.1 is dependent on
You could try excluding this transitive dependency from spring-boot-starter-test/io.jsonwebtoken:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
OR/AND
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
But it's possible that there is something within json-path which depends on something from the older json library, which is no longer in the newer version, so proceed with caution and test everything thoroughly.
There is also a chance that something else brings org.json:json.
To verify, please run mvn dependency:tree and search in the produced output for org.json:json.
Please check this link :
spring-boot issue 8706
Exclusion of android-json from spring-boot-starter-test worked for me.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
I found this on another page. I tried the checked answer here and it didn't work with mine, but when I inserted this into my pom file it worked. I'm running unit tests with mockito and one of the endpoints uses JSONObject.put and was giving me the no such method error.
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
Your destinationAddress and refundAddress are passed as list of address or address array in the JSON while in the HotelswitchHotelOrderRequestBody your destinationAddress and refundAddress are refered to as single Address Element. Update your pojo or JSON and try again. This might be an issue.
You need to convert your POJO to JSONObject using ObjectMapper or include json dependency
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
The issue should be the destinationAddress and refundAddress is mismatch between your JSON and POJO.
Try to change your JSON like this:
{
"depositHotel": "xxx",
"destinationHotel": "aaa",
"depositHotelAmount": "0.2",
"destinationHotelAmount": "4",
"destinationAddress": {
"address": "asdf",
"tag": ""
},
"refundAddress": {
"address": "pio",
"tag": ""
}
}
If you dont want to change your JSON, change your Builder POJO to use Address[] instead of Address object.
You should not need the JSONobject
HttpEntity<HotelswitchHotelOrderRequestBody> entity = new HttpEntity<HotelswitchHotelOrderRequestBody>(order, headers());
if all you want to do is to convert your object to a string then use an object mapper.
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(car)
I've been created a Spring Boot JMS application to receive message from a specific amazon sqs queue. Running as Java Application it receive messages without troubles.
But when I deploy on a wildfly v10.0.0 server it not works.
So, here is my Application class:
#SpringBootApplication
#EnableJms
public class QueueListenerFadeApplication {
private SQSConnectionFactory connectionFactory;
#Value("${aws.access.key}")
private String accessKey;
#Value("${aws.secret.key}")
private String secretKey;
private static final Logger logger =
Logger.getLogger(QueueListenerFadeApplication.class.getName());
#Bean
public JmsListenerContainerFactory<?> myFactory() {
final DefaultJmsListenerContainerFactory factory = new
DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
return factory;
}
private SQSConnectionFactory createSQSConnectionFactory() {
BasicAWSCredentials awsCredentials = new
BasicAWSCredentials(this.accessKey, this.secretKey);
final AmazonSQS sqs = AmazonSQSClient.builder()
.withRegion(Regions.AP_SOUTH_1)
.withCredentials(new
AWSStaticCredentialsProvider(awsCredentials))
.build();
return new SQSConnectionFactory(new ProviderConfiguration(), sqs);
}
#PostConstruct
public void init() {
this.connectionFactory = createSQSConnectionFactory();
}
public static void main(String[] args) {
logger.log(Level.INFO, "Starting Queue Listener...");
SpringApplication.run(QueueListenerFadeApplication.class, args);
}
}
Here is my queue listener class:
#Component
public class QueueListenerReceiveService {
private ObjectMapper objectMapper;
private static final Logger logger =
Logger.getLogger(QueueListenerReceiveService.class.getName());
#JmsListener(destination = "${sqs.queue.name}", containerFactory="myFactory")
public void receiveMessage(#Headers Map<String, Object> messageAttributes, #Payload String json) {
try {
objectMapper = new ObjectMapper();
SQSMessage sqsMessage = objectMapper.readValue(json, SQSMessage.class);
logger.log(Level.INFO, "Message Received=" + sqsMessage);
FadeStarterService.start(sqsMessage.getUseCase(), sqsMessage.getZoneId());
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm using Maven to manage dependencies, so here are the dependencies in pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.311</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>amazon-sqs-java-messaging-lib</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
And finally the build tag in pom.xml
<build>
<finalName>queue-listener-fade</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.0.1.Final</version>
<configuration>
<hostname>locahost</hostname>
<port>9990</port>
<username>deplyusr</username>
<password>pssdploy</password>
</configuration>
</plugin>
</plugins>
</build>