form data is not getting posted to spring controller - spring

Form data:
form dat from UI developer tools
user.username:SS
user.email:SGFG#GMAIL.COM
user.firstName:WWW
user.lastName:FF
ext-gen1170:ENV_DEV
ext-gen1171:false
ext-gen1172:false
user.password:
userGroupPermissions:[{"userName":"SS","groupName":"ENV_DEV","permission":"*"}]
Web.xml for the dispatcher servlet:
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/spring/</url-pattern>
</servlet-mapping>
Controller:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
#ResponseBody
public String createUser(#RequestParam(value = "user.username", required = true) String username,
#RequestParam(value = "user.email", required = true) String email,
#RequestParam(value = "user.firstName", required = true) String firstName,
#RequestParam(value = "user.lastName", required = true) String lastName,
#RequestParam(value = "userGroupPermissions", required = true) UserGroupPermission userGroupPermissions,
#RequestParam(value = "password", required = false) String password) throws IOException {
Above details will be added to handle the request
There are no errors in console but the breakpoint is not hit when I keep the break point in controller.
I am getting 404 for this code.
Extjs:
var url = '/spring/createUser';

There are two ways to resolve this -- change the way you are sending parameters to Java or change the way you are receiving parameters.
Just change Java
To keep things simple you should change Java.
GET requests should use #RequestParam arguments in Spring controllers in a way you specified.
POST/PUT requests should use #RequestBody argument in Spring controllers.
So the Spring controller should look like this:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#ResponseBody
public String createUser(#RequestBody UserParams params)
Obviously if you need the #Transactional part you should also leave it.
Sending various requests with ExtJS
Here are some examples on how to use Ext.Ajax.request to send various types of requests.
I've used Polish in values so you can also see how encoding of UTF-8 text works.
Query string
Sending in query string means things get encoded directly in URL after ?. E.g. /test?firstName=Imi%C4%99&lastName=Nazwisko.
// (Java/Spring can get this with `#RequestParam`)
Ext.Ajax.request({
url: '/test',
method: 'GET',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Form data
This is used when sending forms in a standard way. Things get encoded in the body of the request, but the format is actually the same as for the query string (e.g. firstName=Imi%C4%99&lastName=Nazwisko).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Request payload
This is a JSON communication. Things get encoded in the body of the request, but in a JSON format (e.g. {"firstName":"Imi\u0119","lastName":"Nazwisko"}).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
jsonData: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Query string in PUT/POST request
You can trick ExtJS to pass parameters in the URL rather then request body. When both params and jsonData are present in the Ext.Ajax.request one of them has to be put in the URL.
So to pass params in the query string use this:
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
},
jsonData: {}
});
Note the empty jsonData. This will be encoded in request body as {} and can simply be omitted on the receiving end. In this case Java/Spring.
So this way you would receive all params as #RequestParam arguments in your Spring controller.

Related

Spring Boot Content Type Error even when specified in Kotlin

I have an issue in Spring Boot with Kotlin
I have a function that accepts all major Content Types as defined below:
#PostMapping(
value = ["/users/new"],
consumes = [
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE]
)
fun registerNewUser(
#RequestHeader("X-Forward-For") ipAddress: String?,
newUser: NewUser,
request: HttpServletRequest
): ResponseEntity<ObjectNode> {
var realIPAddress = ipAddress
if (realIPAddress == null) {
realIPAddress = request.remoteAddr
}
return userService.registerUser(realIPAddress!!, newUser)
}
Here is how my NewUser class is defined in kotlin
data class NewUser(val email: String?, val password: String?)
Here is how I am doing the check in the registration function
if (!StringUtils.hasText(newUser.email)) {
return responseHandler.errorResponse(
HttpStatus.BAD_REQUEST,
"Please provide an email address"
)
}
Now when I sent a post request with postman and even axios I keep getting the error as shown in the screenshot below
That error message should only be displayed if email address is not provided. But as you can see clearly, the email address is provided in the JSON Payload.
What could be wrong?
Note: This works when the Content-Type is application/x-www-form-urlencoded but doesn't work when the Content-Type is application/json
put #RequestBody before newUser parameter to specify that input should be inside http body part. by default function parameters in spring are considered to be url parameters which can be further clarified with #RequestParam.
there are 2 ways to insert request parameters into http request. one is to attach request parameters to end of the url and the other is to put in http body with application/x-www-form-urlencoded as the content-type.

Angular6 File Upload (Image) with Spring boot

I have a problem when uploading an image in angular 6.
Angular:
addAvatar(username: string, file: File) {
const headers = new HttpHeaders({
});
const formData: FormData = new FormData();
formData.append('file', file, file.name);
return this.http.post(`${this.API_URL}/addavatar/` + username, formData, {headers});
}
Spring controller:
#PostMapping("/addavatar/{username}")
public ResponseEntity<?> addAvatar(#PathVariable(value = "username") String username, #RequestPart(name = "file", required = false) MultipartFile file) {
return userService.addAvatar(username, file);
}
If I send request in Postman all works, but if I want to send request in Angular then I have a 404.
File Upload in Postman
Response in html
/file/ URI in Postman URL seems to be overlooked at Angular request path literal API_URL. That's why it occurs the 404 error.

Prevent encoding in #FormUrlEncoded retrofit

I need to make a post request such that the json data passed, has key pair value,where the key is data.
For example, if i use jquery as below, data is the key.
$.ajax({
url: “/hello",
data:{ data: JSON.stringify(dataObject) },
type:"POST",
dataType:"json"
});
which is equivalent to
data:{ data: {“firstName”:”john”,"lastName”:”doe”}}.
I am using java spring retrofit, to accomplish the similar. In order to pass the key, i am using #FormUrlEncoded and #Field("data") TypedString userInfo
My retrofit interface is as below
public interface userInfoService {
#FormUrlEncoded
#POST(“/hello")
public Response userInfo(#Field("data") TypedString userInfo);
where TypedString is {"firstName":"john","lastName":"doe"}
However, the request looks something like this
data=%7B%22firstName%22%3A%22john%22%2C%22lastName%22%3A%22doe%22%7D, since it form url encoded.The 3 party api can see the data key, but since it has "=" instea of ":", it cant be parsed
How, do i get the request to avoid = and actually send a decoded request.
I have also tried to use #Body instead of #FormUrlEncoded and #Field. Where #Body has TypedString as {data: {“firstName”:”john”,"lastName”:”doe”}}, but for some reason the 3 party api is not able parse the data key.

Alfresco login api giving Bad Request 400

I am trying to login to alfresco through api. I do not know why it is returning error 400 Bad Request.
The json should be correct and in my ajax call I have also set the content type to 'application/json'.
This is my ajax call.
var jsonData = JSON.stringify({ username : usernameV, password : passwordV });
var request = $.ajax({
settings : {contentType:'application/json'},
type: "POST",
url: "http://---ip---/alfresco/service/api/login",
data: jsonData
});
The json string in the console.
{"username":"admin","password":"admin1"}
Error
400 Bad Request
Request sent by the client was syntactically incorrect
Message in responseJSON object
Unable to parse JSON POST body: A JSONObject text must begin with '{' at character 0"
I suspect this is to do with the way you are setting the contentType as the only ways for this to occur appear to either be empty JSON or an incorrect contentType. Try:
var request = $.ajax({
contentType:"application/json",
type: "POST",
url: "http://---ip---/alfresco/service/api/login",
data: jsonData
});
I have created one java program which was doing same thing.I think you should pass username and password in url.Even if you directly hit below url in browser, It will give you alf_ticket, which is use full in authentication for alfresco.
private static String getAlfticket() throws IOException, JSONException {
String ticket = "";
URL url = new URL("http://hostname/alfresco/service/api/login u="+USERNAME+"&pw="+PASSWORD+"&format=json");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
encoding = encoding == null ? "UTF-8" : encoding;
String json = IOUtils.toString(in, encoding);
JSONObject getData = new JSONObject(json);
System.out.println(getData.getJSONObject("data").get("ticket")
.toString());
ticket =getData.getJSONObject("data").get("ticket").toString();
return ticket;
}
Krutik Jayswal
Alfresco Developer

Self-hosted Web API - Post Param null

I'm trying to set up a simple test to make a POST request to my self-hosted Web-API server.
var config = new HttpSelfHostConfiguration(new Uri(baseAddress));
// add a route
config.Routes.MapHttpRoute(name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
I added a Controller:
public class PayloadController : ApiController
{
public string Get()
{
return "Hello from GET";
}
public HttpResponseMessage PostItem(Payload payload)
{
// payload
//...
}
}
And I do have the corresponding model (making sure it contains properties):
public class Payload
{
public string Date { get; set; }
public string Command { get; set; }
}
I'm using Rest Console on Chrome to test the server, getting correct results for the GET in my controller.
Issueing the following request as POST:
Request Url: http://localhost:8080/api/payload
Request Method: POST
Params: {
"Date": "2012.09.26",
"Command": "Hello"
}
EDIT: Content-Type is set to application/json and encoding to UTF-8
Setting a break-point at the controller shows that the POST params are not correctly deserialized into an Paylod object, the param is null.
What am I possibly missing?
You need to specify the request Content-Type as application/json
Edit
Complete response with info from the comments below:
If you are using REST console's "request parameters" instead of "request payload raw body" it will not generate JSON out of them even when you specify application/json.
You need to paste raw JSON into the raw body field like this: http://screencast.com/t/iRWZqv91
{
"Date": "2012.09.26",
"Command": "Hello"
}
If you are receiving a null post parameter to your controller you need to create a constructor with 0 parameters in your model.
Greetings

Resources