Java Spring - null value errors on using RequestMethod.POST - java

I am working on a login system - and was using previously get methods. When I run the application the ajax request seems correct - but the server side parameters coming in are null?
old code...
-- server side
#SuppressWarnings("unchecked")
#RequestMapping(value = "/login", method = RequestMethod.GET)
#CrossOrigin(origins = {"*"})
public ResponseEntity<?> login(
#RequestParam(value="email", required=false, defaultValue="email") String email,
#RequestParam(value="password", required=false, defaultValue="password") String password,
HttpServletRequest request
) throws Exception {
-- front side
export function fetchAuthentication(data) {
let url = 'http://localhost:8080/login?email=ruperttest2#hotmail.com&password=1234';
return function (dispatch) {
axios.get(url)
.then(function (response) {
dispatch(authSuccess(response));
})
.catch(function (error) {
dispatch(authFail(error));
});
}
}
new code..
-- server side
#SuppressWarnings("unchecked")
#RequestMapping(value = "/login", method = RequestMethod.POST)
#CrossOrigin(origins = {"*"})
public ResponseEntity<?> login(
#PathVariable(value="email", required=false) String email,
#PathVariable(value="password", required=false) String password,
HttpServletRequest request
) throws Exception {
System.out.println("email email>>>"+email);
-- front side
export function fetchAuthentication(data) {
let url = 'http://localhost:8080/login';
return function (dispatch) {
axios.post(url, data)
.then(function (response) {
if(response.status === "success"){
dispatch(authSuccess(response));
}
else{
// fail - user not found for example
dispatch(authFail(response));
}
})
.catch(function (error) {
dispatch(authFail(error));
});
}
}

You can make the input parameters required=true just to make sure you are doing fine in client side.

Related

How should 'missing' request headers be handled by a Spring Boot Controller?

I am writing a Spring Boot application. My controller has 2 custom request headers. I was executing a couple of tests only to find out that my application returns a '404' when the headers are not present.
I however was expecting this to lead to a '400' error?
Can anyone elaborate why this is happening? And how I should handle it properly? As in tell the consumer of the service the headers are missing?
#RestController("fundsConfirmationController")
#RequestMapping(
value="/accounts/{accountId}/funds-confirmations",
headers = {"X-CAF-MSGID", "X-AccessToken"}
)
public class FundsConfirmationController implements FundsConfirmationControllerI{
private FundsConfirmationServiceI fundsConfirmationService;
#Autowired
public FundsConfirmationController(FundsConfirmationServiceI fundsConfirmationService){
this.fundsConfirmationService = fundsConfirmationService;
}
#GetMapping(
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity<?> fundsConfirmation(#RequestHeader(value="X-CAF-MSGID") String messageId,
#RequestHeader(value="X-AccessToken") String accessToken,
FundsConfirmationRequest requestParams) { ... }
2 solutions to do the same.
First using #RequestHeader with required false
#RequestMapping(value = "/{blabla}", method = RequestMethod.POST)
public void post(#RequestHeader(value="X-CAF-MSGID", required=false) String X-CAF-MSGID) {
if(X-CAF-MSGID == null) {
// Your JSON Error Handling
} else {
// Your Processing
}
}
Second using HttpServletRequest instead of #RequestHeader
#RequestMapping(value = "/{blabla}", method = RequestMethod.POST)
public void post(HttpServletRequest request) {
String X-CAF-MSGID = request.getHeader("X-CAF-MSGID");
if(X-CAF-MSGID == null) {
// Your JSON Error Handling
} else {
// Your Processing
}
}

Spring Boot #RestController no respond

I'm starting with Spring and REST application. Currently, I'm developing one application on my own and I stuck.
The app is divided just like standard Spring Boot project. All of the controllers are contained in web package.
One of "standard" controller is responsible for handling HTTP request and returning an HTML website. I have added a REST controller which should respond to POST request from the first controller, but I receive a 404 error.
How it looks like in code?
#RestController
#RequestMapping("/users")
public class UserRestController {
#Autowired
private UserService userService;
#RequestMapping(value = "/user", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
public ResponseEntity<?> getUser(#RequestParam("userId") String userId, Errors errors) {
AjaxUser response = new AjaxUser();
if (errors.hasErrors()) {
response.message = errors.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.joining(","));
return ResponseEntity.badRequest().body(response);
}
response.setUser(userService.getUserById(Integer.getInteger(userId).intValue()));
return ResponseEntity.ok(response);
}
private class AjaxUser {
private User user;
private String message;
public void setUser(User user) {
this.user = user;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
#Override
public String toString() {
return "User { id:" + user.getId() + ", Name: " + user.getName() + ", surname: " + user.getSurname() + "}";
}
}
}
From .js file I send a ajax query which should trigger a rest controller, here is the code:
function sendUserId(id) {
var user = {};
user["userId"] = id;
console.log("USER: ", user);
$.ajax({
type: "POST",
contentType: "application/json",
url: "/users/user",
data: JSON.stringify(user),
dataType: 'json',
cache: false,
timeout: 100000,
success: function (user) {
var json = "<h4>Ajax Response</h4><pre>"
+ JSON.stringify(user, null, 4) + "</pre>";
console.log("SUCCESS : ", user);
},
error: function (e) {
var json = "<h4>Ajax Response</h4><pre>"
+ e.responseText + "</pre>";
console.log("ERROR : ", e);
}
});
}
userId is taken from a html by jQuery, console.log show existing and right value.
Note: There exist a standard user #Controller which is responsible for displaying a user list, it works, problem appear during sending a user id to REST controller. It behaves just like the REST controller doesn't exist and browser return 404 status response. Btw, page use a Spring Secure to login and so on.
Could someone help?
BR Konrad
The controller is looking to have a request parameter that you are missing in the js requesting url
/users/user?userId=1
You can get a user by id like below:
#RequestMapping(value = "{id}", method = RequestMethod.GET)
public ResponseEntity<User> get(#PathVariable("id") int id) {
User user = userService.findById(id);
if (user == null) {
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
So your rest entry point is /users/userid, eg: /users/1
Found this from the post Spring MVC RESTFul Web Service CRUD Example
the problem based on function arguments, REST controller should take String argument and next parse it to JSON object, the response should be String too. Topic can be closed, thanks all to be involved.

Error 400--Bad Request

I have a project based in Spring Web model-view-controller (MVC) framework. The version of the Spring Web model-view-controller (MVC) framework is 3.2.8
I have this controller
#SuppressWarnings("unchecked")
#RequestMapping(value = { "/books/store/product",
"/books/store/product/",
"/books/store/product/{productId}",
"/books/store/product/{productId}/" }, method = { RequestMethod.POST })
public String saveProduct(#ModelAttribute("productForm") ProductForm productForm,
#PathVariable Long productId,
HttpServletRequest request, Model model) throws Exception {
..
}
Everything is fine for this URL : /books/store/product/232
but for this one /books/store/product/
I got this error:
Error 400--Bad Request
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
I've tried to put this #PathVariable(required = false), but I got a compilation error: The attribute required is undefined for the annotation type PathVariable
This is because the service is always waiting for the path variable productId
Because you're using Spring 3 I suggest you to create 2 methods. One with the path variable and the other without it.
#RequestMapping(value = { "/books/store/product",
"/books/store/product/"}, method = { RequestMethod.POST })
public String saveProduct(#ModelAttribute("productForm") ProductForm productForm,
HttpServletRequest request, Model model) throws Exception {
..
}
#RequestMapping(value = { "/books/store/product/{productId}",
"/books/store/product/{productId}/" }, method = { RequestMethod.POST })
public String saveProduct(#ModelAttribute("productForm") ProductForm productForm,
#PathVariable Long productId,
HttpServletRequest request, Model model) throws Exception {
..
}
If you're using Spring 4 and Java 8 I suggest you to use optional.
#PathVariable Optional<Long> productId
If you do not always need productId. Try using query parameter and make it optional. required=false
This url will now look like:
http://localhost:8080/books/store/product?productId=232
http://localhost:8080/books/store/product
Like this:
#SuppressWarnings("unchecked")
#RequestMapping(value = { "/books/store/product",
}, method = { RequestMethod.POST })
public String saveProduct(#ModelAttribute("productForm") ProductForm productForm,
#RequestParam(value = "productId", required = false) Long productId,
HttpServletRequest request, Model model) throws Exception {
..
}
Hope it helps.

Java - #ResponseBody String - error 200

I'm trying to get a string response from my controller but I get the below error:
SyntaxError: Unexpected end of JSON input(…) "Error 200"
When I change the response to a boolean or a different type, it's working ok. The problem is when I try to return a string.
js code:
$.ajax({
method: "POST",
url: "./signup",
data: _data,
dataType: "json",
contentType : "application/json;charset=UTF-8",
success : function(data) {
console.log(data)
},
error : function(qXHR, textStatus, errorThrown){
console.log(errorThrown, "Error " + qXHR.status);
}
});
controller code:
#RequestMapping(value = "/signup", method = RequestMethod.POST, produces = {"text/plain", "application/*"})
public #ResponseBody String signup(#RequestBody UserSignup details) {
//...
return message;
}
any idea how can I solve this problem? I have tried a few things but nothing work. I think the response format is wrong as what the code expects.
Edit
I have changed my code(removed produces) but I still getting the same error:
SyntaxError: Unexpected end of JSON input(…) "Error 200"
#RequestMapping(value = "/signup", method = RequestMethod.POST)
public #ResponseBody String signup(#RequestBody UserSignup details) {
message = "ok";
}
return message;
}
Your method is wrong. You are saying to produce produces = {"text/plain", "application/*"} But you are also adding the #ResponseBody which will generate JSON format response.
I would suggest you remove the attribute produces. And verify the string you are returning is well formed
Try to wrap your response in ResponseEntity class
#RequestMapping(value = "/signup", method = RequestMethod.POST)
public #ResponseBody ResponseEntity<String> signup(#RequestBody UserSignup details) {
message = "ok";
return new ResponseEntity<>(message, HttpStatus.OK);
}
Also double check data that you are sending to server, maybe this is the problem, can you show us _data value?
As I don't have problem when the response is different stuff as a String I have solved the problem creating my own object. So below is the code:
public class Response<T> {
private T message;
private Exception ex;
public Exception getEx() {
return ex;
}
public void setEx(Exception ex) {
this.ex = ex;
}
public T getMessage() {
return message;
}
public void setMessage(T message) {
this.message = message;
}
}
#Controller
public class MyControllerController {
private Response<String> _response;
private String message;
public MyController() { _response = new Response<>(); }
#RequestMapping(value = "/signup", method = RequestMethod.POST)
public #ResponseBody Response<String> signup(#RequestBody UserSignup details) {
try{
message = "";
// code...
_response.setMessage(message);
return _response;
}catch (Exception ex){
_response.setEx(ex);
return _response;
}
}
}
response example in the browser:
Object {message: "", ex: null}

500 Internal Server Error when calling ajax in spring

I am using Spring MVC and I have an AJAX which is used to delete selected user. It's working fine on my local system but when I tried to run the same code on development server I'm getting
500 Internal Server Error
I did google to figure out what is wrong with my code but I'm not able to figure out anything till now. Any help will be appreciated.
AJAX function in my JSP file:
$('.del-btn .userId').click(function(){
var userId = $(this).attr("alt");
var data = 'userId='+ userId;
$.ajax({
type: 'POST',
url: '${pageContext.servletContext.contextPath}/deleteUser',
data: data,
success: function(response) {
$('#submitkpi').submit();
}
});
});
deleteUser function in Controller:
#RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
public #ResponseBody Map<String, ? extends Object> deleteKpi(#ModelAttribute(value = "userId") String userId, BindingResult result) {
if (!userId.isEmpty()) {
userService.deleteUser(userId);
return Collections.singletonMap("ok", true);
}
return Collections.singletonMap("errorMsg", "Unable to complete your request!");
}
Can you try this?!
$('.del-btn .userId').click(function(){
var userId = $(this).attr("alt");
$.ajax({
url: 'deleteUser',
data: ({
userId : userId,
}),
success: function(response) {
alert(response)
}
});
});
Controller
#RequestMapping("/deleteUser")
#ResponseBody
public String deleteKpi(#RequestParam(value = "userId") Long userId, HttpSession session) {
if (null != userId) {
userService.deleteUser(userId);
return "Ok";
}
return "NotOk";
}

Categories