I'm having a hard time figuring out why this request encounter 400 BAD request :
{
email: "ccc#gmail.com"
lastfmUsername: "bluecun"
password: "$2a$10$if246VMeosRCNJibodEhueXGyQNiAHeJd3KVHi7WedjByECYeXO5."
username: "bluecun"
}
Here is my model and controller code :
public class User {
private Long id;
private String username;
private String lastfmUsername;
private String email;
private String password;
...
}
#RequestMapping(value = "/register", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public
#ResponseBody
void register(#RequestBody User user) throws Exception {
semanticGraphDao.saveUser(user);
}
Thanks for the answers.
First you need to check if you JSON is wellformed, which means: properties surrounded by quotes and a colon between each property, for example:
{
"email": "ccc#gmail.com",
"lastfmUsername": "bluecun",
"password": "$2a$10$if246VMeosRCNJibodEhueXGyQNiAHeJd3KVHi7WedjByECYeXO5.",
"username": "bluecun"
}
On the top of that, check the constructor of your User class. It must have a default constructor:
public class User {
private Long id;
private String username;
private String lastfmUsername;
private String email;
private String password;
public User() {
}
// Getters and Setters
}
And finally, check Spring boot logs - probably it is showing some kind of exception from Jackson, which will guide you on how to solve the mapping issue.
Related
I have a requirement that I need to connect a small API to an Oracle DB for few GET ops. Now in dev since there is only 1 instance, it's quite easy to provide. But when it comes to production, the DBs are located in 5 different countries and hence are 5 different instances (All of them are exactly the same except for the data). My idea is to run them via application.properties with active profile and then connect them to application-{active-profile}.properties. Something like below:
application.properties:
spring.profiles.active=DB1
spring.application.name=demo
application-DB1.properties:
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:oracle:thin:#//host1:port/SID
spring.datasource.username=username
spring.datasource.password=password
Configuration class:
#Configuration
#ConfigurationProperties("spring.datasource")
public class DBConfiguration {
private String url;
private String username;
private String password;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Profile("dev")
#Bean
public String devDBConnection(){
System.out.println("URL:"+getUrl());
System.out.println("username:"+getUsername());
System.out.println("password:"+getPassword());
return "DEV DB connection";
}
#Profile("uat")
#Bean
public String uatDBConnection() {
System.out.println("URL:" + getUrl());
System.out.println("username:" + getUsername());
System.out.println("password:" + getPassword());
return "UAT DB connection";
}
}
So when I have to enable the API for another DB, say DB-3 , all I have to do is change the active.profile=DB3 and create a new file application-DB3.properties.
Does this seem a standard practice or is there an way to do this more efficiently ?
A good practice is to pass such configuration as environment variables or system properties.
So you don't need to change the code/configuration when these variables change.
I am using spring boot along with react js and postgresql. I am trying to print the rows of table from postgresql to a react js page. I have used crud repository function findAll() in the controller method to get the List. My problem is that when I am printing the List in spring boot console, it prints the list but it's printing empty objects' list when that url is accessed.
User.java
#Entity
#Table(name="users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
public User() {
}
public User(String name, String email) {
this.name = name;
this.email = email;
}
#Override
public String toString() {
return String.format("User[id=%d, name='%s', email='%s']",this.id,this.name,this.email);
}
}
UserRepository.java
public interface UserRepository extends CrudRepository<User, Long>{
}
WebController.java
public class WebController {
#Autowired
private UserRepository repository;
#GetMapping("home")
public String home() {
System.out.println("whaaat");
return "hi ssup";
}
#GetMapping("/save")
public String process() {
repository.save(new User("vidhi","vd#gmail.com"));
System.out.print("apple ");
return "Done";
}
#GetMapping("findall")
#ResponseBody
public Collection<User> findAll() {
System.out.println("cc");
List<User> users = (List<User>) repository.findAll();
System.out.println(users);
return users;
}
}
On printing users in boot: [User[id=33, name='i', email='vd#gmail.com'], User[id=34, name='v', email='d#gmail.com']
on localhost:8080/findall: [{},{}]
What's going on wrong here? I am very confused and trying to figure this out since a lot of time and it's eating my head.
Any help would be wonderful!
Thanks for your time.
You have to add getters and setters to the User class.
Change it to:
#GetMapping("findall", produces= MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Collection<User>> findAll() {
System.out.println("cc");
List<User> users = (List<User>) repository.findAll();
System.out.println(users);
return ResponseEntity.ok(users);
}
change your repo to:
#Repository
public interface UserRepository extends JpaRepository<User, Long>{
}
Im trying to save info to DynamoDB but im currently getting the error java.lang.NullPointerException: null when using "save" on the AccountHelper class.
I followed the starter guide found on Github; https://github.com/derjust/spring-data-dynamodb
Here is my Model Class;
#DynamoDBTable(tableName = "Users")
public class User {
// #Id
private String _id;
private String bloodGroup;
private String firstName; // DO NOT change this, needs to stay firstName
private String surname;
private String email;
private String password;
private String addressline;
private String postcode;
private String latitude;
private String longitude;
public User() {}
// More Constructors, Getters & Setters
DynamoDB Config Class;
#EnableDynamoDBRepositories(includeFilters = {#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {DynamoDBRepo.class})})
#Configuration
public class DynamoDBConfig {
#Value("${amazon.aws.accesskey}")
private String amazonAWSAccessKey;
#Value("${amazon.aws.secretkey}")
private String amazonAWSSecretKey;
public AWSCredentialsProvider amazonAWSCredentialsProvider() {
return new AWSStaticCredentialsProvider(amazonAWSCredentials());
}
#Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey);
}
#Primary
#Bean
public DynamoDBMapperConfig dynamoDBMapperConfig() {
return DynamoDBMapperConfig.DEFAULT;
}
#Bean
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig config) {
return new DynamoDBMapper(amazonDynamoDB, config);
}
#Bean
public AmazonDynamoDB amazonDynamoDB() {
return AmazonDynamoDBClientBuilder.standard().withCredentials(amazonAWSCredentialsProvider())
.withRegion(Regions.US_EAST_1).build();
}
}
Here is the method/class where i am getting the error;
#Service
public class AccountHelper {
private DynamoDBRepo dynamoDBRepo;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public User create(String bloodGroup, String firstname, String surname, String email, String password, String addressline, String postcode) {
// Getting the error here
return dynamoDBRepo.save(new User(bloodGroup, firstname, surname, email, bCryptPasswordEncoder.encode(password), addressline, postcode));
}
// More methods below that i am not adding to keep this question to a minimum.
Here is my controller;
#Controller
#Component
public class AccountController {
#Autowired
private AccountHelper Service_functions;
#ResponseBody // Works
#PostMapping(value = "/create/{bloodGroup}/{firstname}/{surname}/{email}/{password}/{addressline}/{postcode}")
public String create( #PathVariable String bloodGroup , #PathVariable String firstname, #PathVariable String surname, #PathVariable String email, #PathVariable String password, #PathVariable String addressline, #PathVariable String postcode){
User CreateUser = Service_functions.create(bloodGroup, firstname, surname, email, password, addressline, postcode);
System.out.println("this is working");
return CreateUser.toString();
}
account properties;
spring.application.name=account-service
server.port=8020
eureka.client.service-url.defaultZone=http://localhost:8001/eureka/
amazon.aws.accesskey="" // i removed the keys
amazon.aws.secretkey=""
Any Suggestions/Help would be greatly on where i am going wrong.
Two things you need to fix here based on your details provided.
Add #Autowired annotation on your dynamoDBRepo variable so that it can be recognised as spring managed bean.
Based on your comment
i.e. error saying that it cannot find
com.bdonor.accountservice.Repository.DynamoDBRepo
You need to include com.bdonor.accountservice.Repository package as JPA repository package and enable jpa repository scan in your configuration.
#SpringBootApplication
public class SpringDataSolarApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataSolarApplication.class, args);
}
#Bean
SolrTemplate solrTemplate() {
return new SolrTemplate(solrClientFactory());
}
#Bean
SolrClientFactory solrClientFactory() {
Credentials credentials = new UsernamePasswordCredentials("solr", "SolrRocks");
return new HttpSolrClientFactory(solrClient(), credentials , "BASIC");
}
#Bean
SolrClient solrClient() {
return new HttpSolrClient.Builder("http://localhost:8983/solr").build();
}
}
public interface EmployeeRepository extends SolrCrudRepository{
Employee findByName(String name);
}
#RestController
public class EmployeeController {
#Autowired
private EmployeeRepository repository;
#PostConstruct
public void addEmployees() {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("373", "Basant", new String[] { "Bangalore", "BTM" }));
employees.add(new Employee("908", "Santosh", new String[] { "Hyderbad", "XYZ" }));
employees.add(new Employee("321", "Sagar", new String[] { "Pune", "PQR" }));
repository.saveAll(employees);
}
#GetMapping("/getALL")
public Iterable<Employee> getEmployees() {
return repository.findAll();
}
#GetMapping("/getEmployee/{name}")
public Employee getEmployeeByName(#PathVariable String name) {
return repository.findByName(name);
}
}
the getALL operation is working fine but the save operation failed with this error. Please help
Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:225) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.7.jar:4.5.7]
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.7.jar:4.5.7]
... 63 common frames omitted
Came across same issue and solved with extending HttpSolrClient and applying same backend approach with recommended way mentioned on Solr docs but getting credentials from constructor not setting on each request.
class CustomSolrClient extends HttpSolrClient {
#Nullable
private final String username;
#Nullable
private final String password;
CustomSolrClient(Builder builder, String username, String password) {
super(builder);
this.username = username;
this.password = password;
}
#Override
public NamedList<Object> request(SolrRequest request, ResponseParser processor, String collection) throws SolrServerException, IOException {
HttpRequestBase method = createMethod(request, collection);
if (username != null && password != null) {
String userPass = username + ":" + password;
String encoded = Base64.byteArrayToBase64(userPass.getBytes(UTF_8));
method.setHeader(new BasicHeader("Authorization", "Basic " + encoded));
}
return executeMethod(method, processor, request instanceof V2Request || request.getPath().contains("/____v2"));
}
}
And create bean using that:
#Bean
public SolrClient solrClient() {
return new CustomSolrClient(new HttpSolrClient.Builder(properties.getHost()), properties.getUsername(), properties.getPassword());
}
This may seem as an ugly approach but if you check HttpSolrClientFactory sources it's even more uglier which actually accesses private field of HttpClient belongs to Solr client.
I am very new to angularjs facing some issues to post list of object which inturn has set of objects.Below is my backend bean object strurcture :
public class UserBean{
private String userName;
private Set<ContactBean> contactBean= new HashSet<ContactBean>();
private Set<LocationBean> locationBean= new HashSet<LocationBean>();
//getter and setter over here
}
public class ContactBean{
private String contactName;
private String contactPhone;
private String contactEmail;
//getter and setter over here
}
public class LocationBean{
private String country;
private String state;
private String city;
//getter and setter over here
}
my controller structure is,
#RequestMapping(value = "/addUser", method = {RequestMethod.POST })
public #ResponseBody String addUser(#RequestBody UserBean userBean){
return "";
}
and my angular js script is
var response = $http.post("addUser", JSON.parse(JSON.stringify($scope.userBean,$scope.contactBean,$scope.locationBean,)), config);
I am setting my data-ng-model like this
data-ng-model="userBean.userName"
data-ng-model="contactBean.contactName"
data-ng-model="locationBean.country"
How can I set contact and location bean object to UserBean. Any help would be really appreciated.