I have a JAX-RS project where the POST is not working. I have #GET URLs which work fine. Everything seems to work fine except this #POST.
#POST
#Path("/json/insert")
#Produces(MediaType.APPLICATION_JSON)
#Consumes("application/x-www-form-urlencoded")
public String postJSONInsert(
#FormParam("instance") String instance,
#FormParam("db") String table) {
String json;
EDPObject edp_obj = new EDPObject();
try {
json = edp_obj.insert("json", instance, table);
} catch(Exception e) {
edp_obj.endSession();
json = handleJSONError(e);
}
return json;
}
Getting 500 not yet connected in firebug when trying this on client:
$.ajax('http://127.0.0.1:8070/sixaxis/webapi/json/insert', {
data: {
db: '17:2',
instance: 'shawn'
},
dataType: 'json',
type: 'POST'
});
Have you tried:
#Consumes(MediaType.APPLICATION_JSON)
since your jQuery is:
dataType:'json'
Update (thanks for the feedback):
Then the method at least should be:
#POST
#Path("/json/insert")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String postJSONInsert( Map<String,Object> params ){
// Your business logic
}
Related
From a js page (in angular) I call a REST request, GET method, were I would to pass an header, this is the function that I call from the REST request:
allstaffworking: function(_getstaff){
var currentToken = _GetToken();
var Headers = {
token: currentToken.stringtoken
};
console.log("idtoken"+Headers);
if (currentToken !== null) {
$http({
method : 'GET',
headers: Headers,
url : REST_URL+'staff/working'
}).then(function successCallback(response) {
_getstaff(response)
}, function errorCallback(response) {
console.log(response.statusText);
});
} else {
console.log("NON SEI LOGGATO!!!");
}
},
Whithout headers: Headers, it works, but I want to pass an important json string: {"idtokenStaff":11,"staffType":{"idstaffType":2,"type":"Dipendente"},"tokenStaff":"88d08m8ve4n8i71k796vajkd01"} in the Headers. I don't know How I can take this string in Jersey. This is java file in with I have the REST method:
#Path("/staff")
public class StaffController {
BaseDao sDao = new StaffDaoImpl();
StaffDao stfDao = new StaffDaoImpl();
TokenStaffDao tsDao = new TokenStaffDaoImpl();
TokenStaff ts = new TokenStaff();
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Staff> getStaff()
{
List<Staff> listOfStaff=sDao.getAll(Staff.class);
return listOfStaff;
}
#GET
#Path("/working")
#Produces(MediaType.APPLICATION_JSON)
#Consumes("application/json")
public List<Staff> getWStaff(#HeaderParam("token") String token) throws JSONException
{
JSONObject jsonObj = new JSONObject(token);
Boolean id = tsDao.getExistence(jsonObj.getInt("idtokenStaff"));
if (id){
List<Staff> listOfWStaff=stfDao.getAllW();
return listOfWStaff;
}
else
return null;
}
}
Taking header from: #HeaderParam("token") String token. How Can I take the element of the header?
A bit late to answer this, but you can also use #Context annotation to get httpheaders.
Eg.
public List<Staff> getWStaff(#Context HttpHeaders httpHeaders) {
String token = httpHeaders.getHeaderString("token");
JSONObject jsonObj = new JSONObject(token);
}
I've got Angular app and Java server.
I need to send POST request with JSON object consisting of string array and string field.
I'm using Angularjs $resource and Java javax.ws.rs.
My latest try as follows:
Client:
var messages = $resource('resources/messages/getmessages', {}, {
update: { method: 'POST', url: 'resources/messages/updatemessages' }
});
//...
var _args = { 'msgIdList': ['1', '2', '3'],
'action': 'makeSmth' };
return messages.update(_args).$promise.then(
function (data) {
//...
},
function (error) {
//...
}
)
Server:
#POST
#Path("updatemessages")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.APPLICATION_JSON +"; charset=UTF-8")
public Response updateMessages( #FormParam("msgIdList") List<String> msgIdList,
#DefaultValue("") #FormParam("action") String action,
#CookieParam("rgsid") String c_sid,
#Context HttpServletRequest httpservletreq) {
//...
}
The problem is that I've got 415 Unsupported Media Type error, and don't know what to do next. I've tried lots of things, but may be I was wrong from the start, and I can't pass parameters this way?
Any help would be appreciated, thanks!
you can try this in your angular, maybe it can help.
var sendPost = $http({
method: "post",
url:"JAVA_SERVER_SERVICE_URL",
data: {
msgIdList: 'your_value',
action: 'your_value'
},
headers: { 'Content-Type': 'application/json' }
});
So, eventually I made a wrapper class, so now it looks this way:
#XmlRootElement
private static class RequestWrapper {
#XmlElement
private ArrayList<String> msgIdList;
#XmlElement
private String action;
public ArrayList<String> getMsgIdList() {
return msgIdList;
}
public void setMsgIdList(ArrayList<String> msgIdList) {
this.msgIdList = msgIdList;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public RequestWrapper() {
}
}
#POST
#Path("updatemessages")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON +"; charset=UTF-8")
public Response updateMessages( RequestWrapper requestData,
#CookieParam("rgsid") String c_sid,
#Context HttpServletRequest httpservletreq) {
//...}
Angular part stays unchanged.
I'm not really sure, if this the right way to go (class description and so on), but it works.
I have some JAX-RS web services with method signatures like below. Is it possible to print out the raw JSON requests coming from the clients and raw JSON response returned to the clients?
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response XXX(#Context HttpServletRequest request, Parameters requestParameters) {
...
}
Thanks in advance.
this can be done via request filter for you. This is my implementation:
#Path("test")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class HelloResource {
private static final Logger log = Logger.getLogger(HelloResource.class);
#POST
#Path("/test")
public Response test(String body) {
Map<String, String> tmp = new HashMap<>();
tmp.put("test", "value");
return Response.ok(tmp).build();
}
}
The resource for testing. Just takes the body as a string.
Now you can register a ContainerResponseFilter and a ContainerRequestFilter.
These filters will be called before and after the request. Before will print the incoming body, after will print the response body.
It is important to not do both in the response filter because the request entity Stream is closed at the time the response filter is executed.
That is when you want to print your bodies, e.g. like this:
public class PrintFilter implements ContainerResponseFilter, ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
System.out.println("Response body: " + responseContext.getEntity());
}
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String string = IOUtils.toString(requestContext.getEntityStream());
System.out.println("request body: " + string);
}
}
I am using apache-commons to read the request Stream into a String.
For my json file, looking like that:
artur#pandaadb:~/tmp/test$ cat 1.json
{
"eventType": 1,
"params": {
"field1" : 10
}
}
I can make a curl, looking like this:
artur#pandaadb:~/tmp/test$ curl -XPOST "localhost:9085/api/test/test" -H "Content-Type: application/json" --data #1.json
{"test":"value"}
Which will print to my console:
request body: { "eventType": 1, "params": { "field1" : 10 }}
Response body: {test=value}
That is obviously only one of many solutions. This would work for all json content types (and frankly most other content types as well I would expect).
Hope that helps,
Artur
Can u explain me why DELETE method (store.remove() in Edit.js) throws 400 Bad request. Other method works well. In header request url seems to be ok "http://localhost:8080/Diary/rest/notes/22?_dc=1461837327580".
I know that problem is in payload of DELETE method, store.remove() includes ID as payload. How can i disable that and send DELETE method without body, because ID is already in URL
Rest Service
#Path("/notes")
public class NoteRestService {
#Context
private UriInfo uriInfo;
#Context
private HttpServletRequest request;
private NoteDaoImpl noteDao = new NoteDaoImpl();
#GET
#Produces("application/json")
public String getNotes(){
String login = request.getSession(true).getAttribute("login").toString();
List<Note> notes = noteDao.getUserNotes(login);
return new Gson().toJson(notes);
}
#POST
#Consumes("application/json")
public Response postNote(Note note){
String login = request.getSession(true).getAttribute("login").toString();
note.setUser(login);
noteDao.persist(note);
URI noteUri = uriInfo.getAbsolutePathBuilder().path(Long.toString(note.getId())).build();
return Response.created(noteUri).build();
}
#PUT
#Path("{id}")
#Consumes("application/json")
public Response updateNote(#PathParam("id") String id,Note note){
String login = request.getSession(true).getAttribute("login").toString();
Note editNote = noteDao.getNote(Long.parseLong(id));
note.setCreated(editNote.getCreated());
note.setUser(login);
noteDao.update(note);
return Response.ok().build();
}
#DELETE
#Path("{id}")
public Response deleteNote(#PathParam("id") String id){
Note note = noteDao.getNote(Long.valueOf(id));
if (note==null){
throw new NotFoundException();
}
noteDao.delete(Long.parseLong(id));
return Response.noContent().build();
}
}
EditController.js
Ext.define('MVC.controller.Edit', {
extend: 'Ext.app.Controller',
init: function () {
this.control({
'editForm > button#SaveRecord': {
click: this.onSaveButtonClick
},
'editForm > button#DeleteButton': {
click: this.onDeleteButtonClick
}
});
},
onSaveButtonClick: function (btn) {
//get reference to the form
var detailView = btn.up('editForm');
//get the form inputs
var data = detailView.getValues();
//see if the record exists
var store = Ext.getStore('TestStore');
console.log(data.id);
var record = store.getById(data.id);
if (!record) {
record = Ext.create('MVC.model.Note', {
title: data.title,
created: new Date(),
updated: new Date(),
text: data.text
});
Ext.MessageBox.alert('Created', data.title);
store.insert(0, record);
store.sync();
return;
}
record.set(data);
store.sync();
//manually update the record
detailView.updateRecord();
},
onDeleteButtonClick: function (btn) {
//get reference to the form
var detailView = btn.up('editForm');
//get the form inputs
var data = detailView.getValues();
var store = Ext.getStore('TestStore');
var record = store.getById(data.id);
store.remove(record);
store.sync();
}
});
UPD: Store
Ext.define('MVC.store.TestStore', {
extend: 'Ext.data.Store',
requires: [
'MVC.model.Note'
],
storeId: 'TestStore',
model: 'MVC.model.Note',
autoLoad: false,
proxy: {
type: 'rest',
url: 'rest/notes',
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy:' DELETE'
},
reader: {
type: 'json',
rootProperty: 'data'
},
writer: {
type: 'json',
writeAllFields: true
}
}
});
You can't have a HttpMethod.DELETE with a body.
This is not explicitly stated in the RFC, but some Proxy servers will reject the body if you have one in a delete method. Spring lowers the standard and will reject your query with a Bad Request.
Remove the body as well as the answer to fix your issue.
Check this for more information:
Is an entity body allowed for an HTTP DELETE request?
If TestStore is the store you're using, I'd guess that your problem is here:
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'GET'
},
I don't recognize the #DELETE annotation, so I'm not 100% sure but if your controller is expecting DELETE, and you're sending GET, that could explain the 400 error.
I ma using Spring MVC and trying to use jQuery. I have this on my web page:
$(document).ready(function () {
var entity = {mag: "status_key", paper: "View10"};
$("#btn").click(function () {
$.ajax({
url: "ajaxJsonPost",
type: 'post',
dataType: 'json',
data: JSON.stringify(entity),
contentType: 'application/json',
});
});
});
Spring server has this:
#RequestMapping(value = "ajaxJsonPost", method = RequestMethod.POST)
public void postJson(#RequestBody Entity en) throws IOException {
System.out.println("writing entity: " + en.toString());
}
OK, Entity cames to server. BUT browser console prints 404 not found. I know that my POST request needs any response. In the Internet I've found solution which recommends me to return ResponseEntity object, OR use annotation #ResponseStatus. They both return HttpStatus well, but I don't know in which cases I should use them. What is the best way?
#Controller
#RequestMapping("/apipath")
public class SomeController {
#RequestMapping(value = "/ajaxJsonPost", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public String postJson(#RequestBody final Entity en) {
System.out.println(en.toString());
//assuming you have a class "EntityService" and
//it has a method postData
//which takes Entity object as parameter and pushes into database.
EntityService.postData(en);
System.out.println("added");
return "success";
}
}
Entity object on the Server side
#JsonAutoDetect
public class Entity {
private String mag;
private String paper;
public String getMag() {
return mag;
}
public void setMag(final String mag) {
this.mag = mag;
}
public String getPaper() {
return paper;
}
public void setPaper(final String paper)
this.paper = paper;
}
}
ajax
$(document).ready(function () {
var entity = {mag: "status_key", paper: "View10"};
$("#btn").click(function () {
$.ajax({
url: "/apipath/ajaxJsonPost",
type: 'post',
dataType: 'json',
data: JSON.stringify(entity),
contentType: 'application/json',
success : function(response) {
alert(response);
},
error : function() {
alert('error');
}
});
});
});
And as far as why and when to use #ResponseStatus and #ResponseEntity, there is already a short and simple answer here by #Sotirios Delimanolis. When use #ResponseEntity .
It says :
ResponseEntity is meant to represent the entire HTTP response. You can
control anything that goes into it: status code, headers, and body.
#ResponseBody is a marker for the HTTP response body and
#ResponseStatus declares the status code of the HTTP response.
#ResponseStatus isn't very flexible. It marks the entire method so you
have to be sure that your handler method will always behave the same
way. And you still can't set the headers. You'd need the
HttpServletResponse or a HttpHeaders parameter.
Basically, ResponseEntity lets you do more.