Unsupported Media Type in postman - spring

I am implementing spring security with oauth2 and jwt.
the below is my login function
function doLogin(loginData) {
$.ajax({
url : back+"/auth/secret",
type : "POST",
data : JSON.stringify(loginData),
contentType : "application/json; charset=utf-8",
dataType : "json",
async : false,
success : function(data, textStatus, jqXHR) {
setJwtToken(data.token);
},
error : function(jqXHR, textStatus, errorThrown) {
alert("an unexpected error occured: " + errorThrown);
window.location.href= back+'/login_page.html';
}
});
}
And down I have the Controller
#RequestMapping(value = "auth/secret", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(#RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException {
System.out.println();
logger.info("authentication request : " + authenticationRequest.getUsername() + " " + authenticationRequest.getPassword());
// Perform the security
System.out.println( authenticationRequest.getUsername()+"is the username and "+authenticationRequest.getPassword());
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
authenticationRequest.getUsername(),
authenticationRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
logger.info("authentication passed");
// Reload password post-security so we can generate token
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails, device);
logger.info("token " + token);
// Return the token
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
But when I try the post request with the postman it shows me
{
"timestamp": 1488973010828,
"status": 415,
"error": "Unsupported Media Type",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
"message": "Content type 'multipart/form-data;boundary=----WebKitFormBoundaryY4KgeeQ9ONtKpvkQ;charset=UTF-8' not supported",
"path": "/TaxiVis/auth/secret"
}
But when I do cosole.log(data) in the ajax call it prints the token?I could not figure out what is wrong.Any help is appreciated.

You need to set the content-type in postman as JSON (application/json).
Go to the body inside your POST request, there you will find the raw option.
Right next to it, there will be a drop down, select JSON (application.json).

Http 415 Media Unsupported is responded back only when the content type header you are providing is not supported by the application.
With POSTMAN, the Content-type header you are sending is Content type 'multipart/form-data not application/json. While in the ajax code you are setting it correctly to application/json. Pass the correct Content-type header in POSTMAN and it will work.

I also got this error .I was using Text inside body after changing to XML(text/xml) , got result as expected.
If your request is XML Request use XML(text/xml).
If your request is JSON Request use JSON(application/json)

If you are still failing with Unsupported Media Type in postman
when calling a SOAP endpoint you could try:
Content-Type: application/soap+xml

i was also having a similar issue. in my case i made two changes
Click on headers tag and add a key 'Content-Type' with Value 'application/json'
Second step is to click on Body tab and select 'raw' radio button and select type as 'JSON' from dropdown as shown below

I had this problem. I had authentication on the authentication tab set up to pass credentials in body.
This error occurred for me when I had the Body set to None.
So I needed an empty body in postman, set to raw JSON to allow this to work even though my main request was parameters in the querystring.
{
}

When this was happening with me in XML;
I just changed "application/XML" to be "text/XML",
which solved my problem.

Related

Subscribing to Angular 6 POST request

Scenario
I have an Angular 6 front end that communicates with a Spring Boot back end. The back end uses PostgreSQL as a database. The thing I want to do is to send a username to the data base and then return his email and print it on a page using Angular 6.
But, I am struggling with the Angular POST request where on subscribing to it I get a JSON parsing error in Chrome developer tools.
Code
Spring Boot
This works fine as I have tested it by printing the email returned from the database on the console.
#RequestMapping(value = "/reset", method = RequestMethod.POST)
public String resetMail(#RequestBody String username) {
try{
User user = userService.findByUsername(username);
//System.out.println(user.getEmail()); Testing purpose
return user.getEmail();
}catch(Exception e) {
//e.printStackTrace(); Prints out NullException StackTrace.
return "Not Present";
}
}
Angular 6
In the following code, I think the problem is in the subscription method as I am getting a JSON parsing error in Chrome developer tools.
httpOptions = { headers: new HttpHeaders({'Content-Type':'text/plain', 'Access-Control-Allow-Origin': '*'})};
reset(username:string) {
this.http.post('http://localhost:8090/reset', username, this.httpOptions).subscribe(data=> {
this.email = data as any;
});
}
console.log(this.email) // Prints undefined
Error
HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:8090/reset", ok: false, …}
>error: {error: SyntaxError: Unexpected token a in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttp…, text: "abcdefg#yahoo.com"}
>headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure during parsing for http://localhost:8090/reset"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:8090/reset"
You want to serialize a string to JSON. If your controller would return an object the #RestController annotation would serialize it properly. In case you want to return just a string you have to return JSONObject.quote(user.getEmail()); You can get the JSONObject dependency from here http://mvnrepository.com/artifact/org.json/json
But I encourage you to always return objects as a response from your rest controllers.

Content type 'text/plain;charset=UTF-8' not supported error in spring boot inside RestController class

I got the following #RestController inside a spring boot application :
#Data
#RestController
public class Hello {
#Autowired
private ResturantExpensesRepo repo;
#RequestMapping(value = "/expenses/restaurants",method = RequestMethod.POST,consumes =MediaType.APPLICATION_JSON_VALUE ,
headers = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public void hello(#RequestBody ResturantExpenseDto dto)
{
Logger logger = LoggerFactory.getLogger("a");
logger.info("got a request");
ResturantExpenseEntity resturantExpenseEntity = new ResturantExpenseEntity();
resturantExpenseEntity.setDate(new Date(System.currentTimeMillis()));
resturantExpenseEntity.setName(dto.getName());
resturantExpenseEntity.setExpense(dto.getExpense());
repo.save(resturantExpenseEntity);
}
}
When I try to send request from restClient/RestedClient (both addons of mozila) I get the following error :
{
"timestamp": 1512129442019,
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'text/plain;charset=UTF-8' not supported",
"path": "/expenses/restaurants"
}
This eror states that the end point doesnt support Json content,But I did
put
consumes =MediaType.APPLICATION_JSON_VALUE
inside #RequestMapping annotation
What am I missing?
Late response but I had the same problem posting the answer it might be useful to someone so I installed Postman and then just change your Content-Type to application/json
If the request is made like this: then it will resolve the issue.
curl -X PUT -H 'Content-Type: application/json' -i http://localhost:8080/spring-rest/api/employees/500 --data '{
"name": "abc",
"email": "abc.a#gmail.com",
"salary": 10000
}'
I see the headers are proper: headers = MediaType.APPLICATION_JSON_VALUE
but when the request is made, at that time we need to inform the handler that its a application/json mime type.
This is late too, but in RESTClient(Mozilla addon), you can add Content-Type: application/JSON from the Headers dropdown menu and even at the response side change it to JSON format
if you are using html with ajax.Check the request header and the payload. Make sure the ajax has the following fields
url : your url
type : 'post',
dataType: "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify( your payload )
if the ajax call has the following fields remove them and try again
processData : false,
contentType : false,

Cross domain put call does not work with Access-Control-Allow-Origin

I am facing problem related to cross domain PUT call , i have allowed Access-Control-Allow-Origin from server side put still it doesn't work.
#PUT
#Path("/getresponse/{caller}")
#Produces({MediaType.APPLICATION_JSON})
public Response getResponseData(#PathParam("caller") String caller ,#QueryParam("ticket")String ticket ,#FormParam("formParam") String data){
ResponseBuilder resp;
System.out.println("name of caller is -> "+ caller);
System.out.println("query param ticket -> "+ ticket);
System.out.println("form param data->" + data);
Employee emp = new Employee();
emp.setAge(23);
emp.setName("data");
Gson gson = new Gson();
String responseJson = gson.toJson(emp);
resp=Response.ok(responseJson);//header("Access-Control-Allow-Origin", "*")
resp.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS");
return resp.build();
}
whenever i call it from jquery ajax method it says
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
I have same replica of above service but with POST signature when i call that service it calls service without any problem
Post service code is
#POST
#Path("/getresponses/{caller}")
#Produces({MediaType.APPLICATION_JSON})
public Response getResponseData1(#PathParam("caller") String caller ,#QueryParam("ticket")String ticket ,#FormParam("formParam") String data){
ResponseBuilder resp;
System.out.println("name of caller is -> "+ caller);
System.out.println("query param ticket -> "+ ticket);
System.out.println("form param data->" + data);
Employee emp = new Employee();
emp.setAge(23);
emp.setName("data");
Gson gson = new Gson();
String responseJson = gson.toJson(emp);
resp=Response.ok(responseJson);//header("Access-Control-Allow-Origin", "*")
resp.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST");
return resp.build();
}
My client side code is
$(document).ready(function(){
// for post service
$('#sendcall').on('click',function(e){
var dataTosend ="formParam=data to send";
$.ajax({
url: 'http://someip:8099/Jqgrid/rest/getdata/getresponses/data?ticket=tick',
contentType : 'application/x-www-form-urlencoded',
data :dataTosend,
type: 'POST',
success: function(data){
alert(data);
}
});
});
//for PUT service
$('#sendcall2').on('click',function(e){
var datatosend ="formParam=data to send";
$.ajax({
url: 'http://someip:8099/Jqgrid/rest/getdata/getresponse/aliahsan?ticket=tick',
contentType : 'application/x-www-form-urlencoded',
data :datatosend,
type: 'PUT',
crossDomain:true,
beforeSend: function (xhr) {
console.log('header added');
},
success: function(data){
alert(data);
}
});
});
});
Please help me in this regard why PUT is not working with this.
Any help will be greatly appreciated
Instead of adding all the CORS headers inside your resource method, use a Jersey filter, as described in this post. The reason for this, is the CORS preflight request, which is defined in HTTP access control (CORS) as:
"preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send.
So the request is an OPTIONS request and it expects back the the "Accept-Xxx" CORS headers to determine what is allowed by the server. So putting the headers in the resource method has no affect as the the request is made with the OPTIONS HTTP method, which you don't have a resource method for. This generally leads to a 405 Method Not Allowed error sent to the client.
When you add the headers in the filter, every request goes through this filter, even the OPTIONS request, so the preflight gets the according headers.
As for the PUT, also described in the above linked document (continuing from the above quote)
Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:
It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
This is why the POST request doesn't face the same problem.

PDF File is not getting downloaded. Ajax call failing with transfer-encoding as chunked

I am working on an application which allows the user to download a file on a button click. on click of a button I make an ajax call and that calls a spring controller. Inside that spring controller i have written a function as below:
#RequestMapping(value="/downloadFile", method=RequestMethod.GET)
public #ResponseBody String dowloadPDF(final HttpSession session, final HttpServletResponse response,#RequestParam(value="param1", required=true)final String param1,#RequestParam(value="param2",required=true)final String param2,#RequestParam(value="param3", required=true)final String param3,#RequestParam(value="fileName",required=true)final String fileNameRecieved){
final String fileName = fileNameRecieved.trim();
final String requestedFile = getPath(param1,param2,param3,fileName);
try{
File pdfFile= new File(requestedFile);
final InputStream inputStream = new FileInputStream(pdfFile);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition","attachment;filename="+fileName);
IOUtils.copy(inputStream, response.getOutputStream());
response.flushBuffer();
inputStream.close();
}catch(Exception exception){
System.out.println("stckTrace : "+exception.getStackTrace());
exception.printStackTrace();
}
return "success";
}
and the ajax call written on a button click is as below.
$.ajax({
url : "downloadFile",
method : "GET",
dataType: "json",
contentType: 'application/pdf',
'Transfer-Encoding': 'chunked',
sync:true,
data:{
"param1" :param1,
"param2":param2,
"param3" :param3,
"fileName": fileName
},
success : function(response) {
alert(response);
},
error : function(e) {
alert('Error: ' + e.getAllResponseHeaders());
}
});
The problem is my controller is getting called and executed without giving any exceptions. but no file was not downloaded and also i am getting error in the response of ajax call stating that
"Server: Apache-Coyote/1.1
Content-Disposition: attachment;filename=GATE-CS 2004.pdf
Content-Type: application/pdf
Transfer-Encoding: chunked
Date: Thu, 05 Feb 2015 16:33:22 GMT
"
Any one can please help me on this, I have changed the content type in ajax call as well, still it is not working.
One problem seems to be related with dataType and contentType in the ajax call.
I think you have swapped their value in ajax call.As per your problem description ,their value should be.
dataType:'application/pdf','Transfer-Encoding': 'chunked'
contentType : "json"//but you don't need to use it,because you are not sending the json data

ajax from Chrome-Extension processed, but receive responseText="" and status=0

I am writing a google-chrome extension, that needs to make ajax requests to a server, send some data, and receive some data back. My server is Tomcat 6.0, running on localhost.
I am able to receive all the data on the server side, do all the processing I need, and send a response back to the extension,
but the status i get in the callback is 0, and responseText="".
my guess is that the problem lies either in the server - returning a response to a request originating from chrome-extension://... url, or in the extension - receiving a response from localhost:8080.
I've set the necessary permissions of course, and I tried setting content-type of the response to "text/xml", "text/html" and "text/plain" - it makes no difference.
I've tried using ajax both with XMLHttpRequest and JQuery - same problem with both.
I've found these issues, but they don't seem to solve my problem:
1. http://www.plee.me/blog/2009/08/ajax-with-chrome-empty-responsetext/
2. http://bugs.jquery.com/ticket/7653
here's my code:
bg.js (background page)
function saveText(data) {
var requrl = serverUrl + addTextUrl;
var params = json2urlParams(data);
jQuery.ajax({
type : "POST",
url : requrl,
data : params,
success : function (data, textStatus, XMLHttpRequest) {
console.log("Data Saved: " + msg);
}
});
// var xhr = new XMLHttpRequest();
// xhr.open("POST", requrl, true);
// xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// xhr.onreadystatechange = function (progress) {
// if (xhr.readyState == 4) {
// console.log("Data Saved: " + this.response);
// }
// };
// xhr.send(params);
}
addContentServlet.java: (server side)
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
ErrorCodes error = addContent(request, response);
response.setContentType("text/plain");
//response.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
//response.setIntHeader("errorCode", error.ordinal());
response.getWriter().write(error.toString());
response.setIntHeader("errorcode", error.ordinal());
if(error == ErrorCodes.SUCCESS){
response.setStatus(error.toHttpErrorCode());
response.flushBuffer();
}
else{
response.sendError(error.toHttpErrorCode(), error.toString());
}
}
EDIT:
I've noticed in the chrome console of the background page that for every ajax that returns to the extension i get a
XMLHttpRequest cannot load
http:// localhost:8080/stp_poc/MyServlet.
Origin
chrome-extension://fmmolofppekcdickmdcjflhkbmpdomba
is not allowed by
Access-Control-Allow-Origin.
I tried loosing bg.js and puting all the code in the main page instead - to no avail.
how come XMLHttpRequest agrees to send the request, but not receive it back??
Maybe a server-configuration problem? I'm a newb, so maybe i missed something basic, like a header in the response
EDIT
I've finally pinned the problem:
I shouldn't have included the port number in my permission. Here's the wrong permission I wrote:
"permissions" : [
"http://localhost:8080/"
]
And here's the correct form:
"permissions" : [
"http://localhost/"
]
everything seems to works fine now.
The problem was that I shouldn't have included the port number in my permission.
Here's the wrong permission I wrote:
"permissions" : [
"http://localhost:8080/"
]
And here's the correct form:
"permissions" : [
"http://localhost/"
]

Resources