Currently Im new to spring and I tried the example (https://spring.io/guides/gs/rest-service/) they have on their website. I think I followed all steps correctly, but with a httpget in postman I only get this response:
"timestamp": "2023-01-04T09:23:03.965+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/greeting"
Here is the Code:
Greeting.java:
package com.example.restservice;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
GreetingController.java:
package com.example.restservice;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
and here is the build.gradle:
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.1'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.session:spring-session-core'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
tasks.named('test') {
useJUnitPlatform()
}
I looked through the linked github and saw, that they have a RestServiceApplication.java, which is never created in the tutorial. After I added that, everything works fine now :)
Related
I am working on a Junit5 integration testing with spring-test-mongo. While executing the below code, I am facing invalid method reference error.
import com.jupiter.tools.spring.test.mongo.annotation.MongoDataSet;
import com.jupiter.tools.spring.test.mongo.junit5.meta.annotation.MongoDbIntegrationTest;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
#MongoDbIntegrationTest
public class JUnit5ExampleTest {
#Autowired
private MongoTemplate mongoTemplate;
#Test
#MongoDataSet(value = "/dataset/bar_dataset.json")
void testPopulatingByMongoDataSet() throws Exception {
Bar simpleDoc = mongoTemplate.findById("55f3ed00b1375a48e618300b", Bar.class);
Assertions.assertThat(simpleDoc)
.isNotNull()
.extracting(Bar::getId, Bar::getData);
}
}
Bar.class
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document
#AllArgsConstructor
#NoArgsConstructor
#Data
public class Bar {
#Id
private String id;
private String data;
}
build.gradle:
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.projectlombok:lombok:1.18.20'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'com.jupiter-tools:spring-test-mongo:0.15'
testImplementation 'org.springframework.boot:spring-boot-starter-data-mongodb:2.5.4'
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.5.4'
testImplementation 'org.projectlombok:lombok:1.16.20'
}
test {
useJUnitPlatform()
}
This error appears, I read on the sites to fix it I need to add various dependencies. I have already added everything I could, it has not disappeared. Tell me what is wrong please.
my implementation
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
// postgresql
implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.19'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
implementation group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.4.30.Final'
//lombok
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
// spring-security-taglibs
implementation group: 'org.springframework.security', name: 'spring-security-taglibs', version: '5.4.2'
// javax.servlet
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
Class User
import lombok.Data;
import org.springframework.data.annotation.Id;
import javax.persistence.*;
import java.util.Set;
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String username;
#Column
private String password;
#Transient
#Column
private String passwordConfirm;
#Column
#ManyToMany(fetch = FetchType.EAGER)
private Set<Role> roles;
}
Class Role
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.*;
import java.util.Set;
#Data
#Entity
#Table(name = "t_role")
public class Role implements GrantedAuthority {
#Id
#Column
private Long id;
#Column
private String name;
#Transient
#ManyToMany(mappedBy = "roles")
private Set<User> users;
public Role(Long id) {
this.id = id;
}
public Role(Long id, String name) {
this.id = id;
this.name = name;
}
#Override
public String getAuthority() {
return getName();
}
Class WebSecurityConfig
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserService userService;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf()
.disable()
.authorizeRequests()
//Доступ только для не зарегистрированных пользователей
.antMatchers("/registration").not().fullyAuthenticated()
//Доступ только для пользователей с ролью Администратор
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/news").hasRole("USER")
//Доступ разрешен всем пользователей
.antMatchers("/", "/resources/**").permitAll()
//Все остальные страницы требуют аутентификации
.anyRequest().authenticated()
.and()
//Настройка для входа в систему
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/");
}
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
}
}
Logs
Error starting ApplicationContext. To display the conditions report re-run
your application with 'debug' enabled.
2021-05-05 12:32:55.159 ERROR 11924 --- [ main]
o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'entityManagerFactory' defined in class path resource
Invocation of init method failed; nested exception is
org.hibernate.AnnotationException: No identifier specified for entity:
com.project.project.model.Role
at
at
... 17 common frames omitted
Process finished with exit code 1
Application.properties
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/main_bd
spring.datasource.username=mysql
spring.datasource.password=mysql
spring.jpa.show-sql=true
spring.jpa.generate-ddl=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
Class UserService
#Service
public class UserService implements UserDetailsService {
#PersistenceContext
private EntityManager em;
#Autowired
UserRepository userRepository;
#Autowired
RoleRepository roleRepository;
#Autowired
BCryptPasswordEncoder bCryptPasswordEncoder;
#Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("Пользователь не найден");
}
return (UserDetails) user; // ПРОВЕРИТЬ!
}
public User findUserById(Long userId) {
Optional<User> userFromDb = userRepository.findById(userId);
return userFromDb.orElse(new User());
}
public List<User> allUsers() {
return userRepository.findAll();
}
public boolean saveUser(User user) {
User userFromDB = userRepository.findByUsername(user.getUsername());
if (userFromDB != null) {
return false;
}
user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
return true;
}
public boolean deleteUser(Long userId) {
if (userRepository.findById(userId).isPresent()) {
userRepository.deleteById(userId);
return true;
}
return false;
}
}
I tried all the tips I found and nothing helped. Can you please tell me what is my mistake here?
the error is org.hibernate.AnnotationException: No identifier specified for entity: com.project.project.model.Role.
Hibernate is telling you that your entity Role has not an id associated. This is because you #Id annotation in your entity is from org.springframework.data.annotation package, and not from javax.persistence.
Try changing the import for #Id to javax.persistence.Id
I have a very simple Spring Boot MVC project in which I try to use the DomainClassConverter to load the Entity directly. But it seems that the DomainClassConverter is not found. I have the following error when accessing to accessing to the 'localhost:8080/one/2' url:
Cannot convert value of type 'java.lang.String' to required type 'com.example.test.data.Customer': no matching editors or conversion strategy found
But The DomainClassConverter should be enabled by Spring Boot and manage the conversion.
I tryed also to enable it explicitely via the #EnableSpringDataWebSupport annotation but it didn't work neither.
Here is my controller code:
#Controller
public class TestController {
#Autowired
private CustomerRepository customerRepository;
#GetMapping("/all")
public void all(Model model) {
Iterable<Customer> customers=customerRepository.findAll();
model.addAttribute("customers",customers);
};
#GetMapping("/one/{customer_id}")
public void one(#PathVariable("customer_id") Customer customer, Model model) {
model.addAttribute("customer",customer);
};
}
The Customer coode:
#Entity
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Getter
private Long id;
#Getter
#Setter
private String firstName;
#Getter
#Setter
private String lastName;
protected Customer() {
}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
The CustomerREpositoy:
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
Customer findById(long id);
}
The application :
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class);
}
}
And finally the build.graddle:
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
// testImplementation 'org.springframework.security:spring-security-test'
}
test {
useJUnitPlatform()
}
Any idea?
you try to get the customer_id (path variable) as a Customer object. hence, get the above error when you try to access localhost:8080/one/2.
change the customer_id (path variable) data type to relevant data type (String, int etc.) as follows,
#GetMapping("/one/{customer_id}")
public void one(#PathVariable("customer_id") String customerId, Model model) {
----
};
Getting Build error when using #Query in Dao class (room persistence library)
I am using both java and kotlin in my project so there may be problem of dependencies, I tried different implementation and kapt but no luck.
My dependencies (see at last for room persistence library)
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//noinspection GradleCompatible
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
implementation 'com.google.android.material:material:1.1.0-alpha05'
implementation "org.jetbrains.anko:anko:$anko_version"
implementation "org.jetbrains.anko:anko-commons:$anko_version"
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.dagger:dagger:2.19'
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
implementation 'com.google.firebase:firebase-database:16.1.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
kapt 'com.google.dagger:dagger-android-processor:2.19'
kapt 'com.google.dagger:dagger-compiler:2.19'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
//BUTTER KNIFE
implementation 'com.jakewharton:butterknife:10.1.0'
kapt 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
//crashlytics
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
// Update your firebase-core version, if it's lower than v11.4.2
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.0.5'
//firebase messaging
implementation 'com.google.firebase:firebase-messaging:17.5.0'
//sms retrival
implementation 'com.google.android.gms:play-services-base:16.1.0'
implementation 'com.google.android.gms:play-services-identity:16.0.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.android.gms:play-services-auth-api-phone:16.0.0'
implementation project(':library')
//for intro
implementation 'com.github.AppIntro:AppIntro:5.1.0'
//picaso
implementation 'com.squareup.picasso:picasso:2.71828'
//room
def room_version = "1.1.1"
implementation "android.arch.persistence.room:runtime:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
My Entity Class
#Entity(tableName = "product")
public class Product
{
#PrimaryKey
#ColumnInfo(name = "id")
public Integer id;
#ColumnInfo(name = "category")
public String category;
#ColumnInfo(name = "name")
public String name;
#ColumnInfo(name = "price")
public Double price;
#ColumnInfo(name = "desc")
public String desc;
#ColumnInfo(name = "img_url")
public String img_url;
public Product(Integer id, String category, String name, Double price, String desc, String img_url) {
this.id = id;
this.category = category;
this.name = name;
this.price = price;
this.desc = desc;
this.img_url = img_url;
}
}
My Dao Class which is building good when not using #Query,
but when #Query is in used, building error causes.
#Dao
public interface CartDao
{
#Query("SELECT * FROM product")
ArrayList<Product> getAllProduct();
#Delete
void delete(Product cart);
}
Build Error
org.gradle.execution.MultipleBuildFailures: Build completed with 1 failures..
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:kaptPureshDebugKotlin'...6 more
Caused by: org.gradle.api.GradleException: Compilation error. See log for more details
at org.jetbrains.kotlin.gradle.tasks.TasksUtilsKt.throwGradleExceptionIfError(tasksUtils.kt:14)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:135)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runCompilerAsync(GradleKotlinCompilerRunner.kt:152)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runCompilerAsync(GradleKotlinCompilerRunner.kt:147)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runJvmCompilerAsync(GradleKotlinCompilerRunner.kt:87)
at org.jetbrains.kotlin.gradle.internal.KaptWithKotlincTask.compile(KaptWithKotlincTask.kt:72)..34 more
#Dao
public interface CartDao
{
#Query("SELECT * FROM product")
ArrayList<Product> getAllProduct();
#Delete
void delete(Product cart);
}
Instead of ArrayList use List
I also had this same error run clean build, invalidate caches or try run with
gradlew assembleDebug
This will show you where is the problem in you app.
I have a problem with retrofit and XML, I use SimpleXmlConverterFactory, and I have this error : Caused by: "java.lang.IllegalArgumentException: Could not locate ResponseBody converter for java.util.List.
Tried:
* retrofit2.BuiltInConverters * retrofit2.converter.simplexml.SimpleXmlConverterFactory"
gradle:
compile 'com.google.code.gson:gson:2.8.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile ('com.squareup.retrofit2:converter-simplexml:2.3.0') {
exclude group: 'xpp3', module: 'xpp3'
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
}
service :
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.client(buildHttpClient())
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
private OkHttpClient buildHttpClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return (new OkHttpClient.Builder())
.addInterceptor(buildDefaultHeadersInterceptor())
.addNetworkInterceptor(buildLogInterceptor())
.build();
}
model :
#Root(name = "item")
public class Item {
#Element(name = "link")
private String link;
#Element(name = "title")
private String title;
#Element(name = "description")
private String description;
public Item() {}
}
xml :
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
<channel xml:lang="fr">
<title>...</title>
<link>http://www.jouars-pontchartrain.fr/</link>
<description>...</description>
<language>fr</language>
<generator>SPIP - www.spip.net</generator>
<image>...</image>
<item xml:lang="fr">
<title>
title here
</title>
<link>
link here
</link>
<description>
description here
</description>
</item>
<item xml:lang="fr">...</item>
<item xml:lang="fr">...</item>
<item xml:lang="fr">...</item>
<item xml:lang="fr">...</item>
</channel>
</rss>
Faced with the same problem. The solution is to make the internal class static (or just create a new separate java class). Also add the "Root" annotation for the "channel" node.
#Root(name = "rss", strict = false)
public class ArticleResponse {
#Element(name = "channel")
private Channel channel;
#Root(name = "channel", strict = false)
static class Channel {
#ElementList(inline = true, name="item")
private List<Article> articles;
}
}
The same with the "enclosure" and "source" nodes - create new files or create static internal classes.
public class Enclosure {
#Attribute(name = "url")
private String url;
#Attribute(name = "length")
private long length;
#Attribute(name = "type")
private String type;
}