Reputation:
Im doing a REST server and client using java to learn. Everything works ok but the PUT request from the client dont pass the data in the body correctly because when I see the log in the server the parameters are NULL
This is the client PUT request code:
private static class Mod {
int idUser;
String nameUser;
String passwordUser;
public Mod(int idUser, String nameUser, String passwordUser) {
this.idUser = idUser;
this.nameUser = nameUser;
this.passwordUser = passwordUser;
try {
URL url = new URL("http://localhost:8080/api/users/" + idUser + "/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("PUT");
connection.setDoInput(true);
connection.setDoOutput(true);
HashMap<String, String> postDataParams = new HashMap<>();
postDataParams.put("nameUser", this.nameUser);
postDataParams.put("passwordUser", this.passwordUser);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
writer.write(getPutDataString(postDataParams));
writer.flush();
writer.close();
os.close();
if (connection.getResponseCode() == 201) {
System.out.println("Modified");
connection.disconnect();
} else {
System.out.println("Error");
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private String getPutDataString(HashMap<String, String> params) {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first) {
first = false;
} else {
result.append("&");
}
result.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
return result.toString();
}
}
This is the code for the POST request. It uses the same way of "injecting" the parameters and works perfect:
private static class Create {
String nameUser, passwordUser;
public Create(String nameUser, String passwordUser) {
this.nameUser = nameUser;
this.passwordUser = passwordUser;
try {
URL url = new URL("http://localhost:8080/api/users/");
HttpURLConnection myConnection = (HttpURLConnection) url.openConnection();
myConnection.setRequestMethod("POST");
HashMap<String, String> postDataParams = new HashMap<>();
postDataParams.put("nameUser", this.nameUser);
postDataParams.put("passwordUser", this.passwordUser);
myConnection.setDoInput(true);
myConnection.setDoOutput(true);
OutputStream os = myConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
myConnection.getResponseCode();
if (myConnection.getResponseCode() == 201) {
System.out.println("Created");
myConnection.disconnect();
} else {
System.out.println("Error");
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private String getPostDataString(HashMap<String, String> params) {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first) {
first = false;
} else {
result.append("&");
}
result.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
return result.toString();
}
}
The REST Controller in the server:
@RestController
@RequestMapping("/api")
public class UserRestController {
@Autowired
private IUserService userService;
@GetMapping("/users")
public List<User> index() {
return userService.findAll();
}
@GetMapping("/users/{id}")
public User show(@PathVariable Long id) {
return this.userService.findById(id);
}
@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
public User create(@ModelAttribute User user) {
this.userService.save(user);
return user;
}
@PutMapping("/users/{id}")
@ResponseStatus(HttpStatus.CREATED)
public User update(@ModelAttribute User user, @PathVariable Long id) {
User currentUser = this.userService.findById(id);
currentUser.setNameUser(user.getNameUser());
currentUser.setPasswordUser(user.getPasswordUser());
this.userService.save(currentUser);
return currentUser;
}
@DeleteMapping("/users/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
this.userService.delete(id);
}
}
Upvotes: 1
Views: 2614
Reputation: 884
You should use x-www-form-urlencoded
because you are not sending any file.
Moreover, you need more work to manually do a form-data
request so it's better to change the server so that it accepts x-www-form-urlencoded
parameters.
After you have modified the server, add the content type to the request:
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
and remove this line:
connection.setDoInput(true)
because you use the HttpURLConnection
as output.
Note that you can make the PUT request easily with Apache HttpClient.
Upvotes: 1