java - Spring RestController - jQuery PUT works only when changing certain values -
hello , thank in advanced:
i'm using spring 4 , jquery trying put data restcontroller. have 3 values passed controller: id, name, genre. reason, put request works every time change name field, if try update genre field, request never hits controller , fails 400: bad request.
i'm totally stumped. get, post, , delete methods working fine too. i'm going include config stuff since there's possibility may issue...
manage-artist.js (knockout , jquery):
... //update artist self.updateartist = function(artist){ self.clearmessages(); //put database $.ajax({ url: "../artist/" + artist.id(), method: "put", data: "id="+artist.id()+"&name="+artist.name()+"&genre="+artist.genre(), datatype: "json", success: function (data) { console.log("artist succesfully updated."); //update message self.successmessage("artist updated."); }, error: function (err) { console.log("an error occured while trying update artist."); //extract json response self.errorresponse(err.responsejson); //...more error handling } }); }; ...
artistcontroller.java:
@restcontroller @requestmapping(value="/artist") public class artistcontroller { @autowired private artistservice artistservice; @autowired private artistvalidator artistvalidator; @initbinder private void initbinder(webdatabinder binder) { binder.setvalidator(artistvalidator); } @requestmapping(value="/", method=requestmethod.get) public list<artist> newartistpage() { return artistservice.findall(); } @requestmapping(value="/{id}", method=requestmethod.get) public artist artistlistpage(@pathvariable integer id) { return artistservice.findbyid(id); } @requestmapping(value="/", method=requestmethod.post) public artist createartist(@modelattribute @valid artist artist, bindingresult result) { //if there's validation errors if (result.haserrors()) throw new invalidrequestexception("error creating artist", result); return artistservice.create(artist); } @requestmapping(value="/{id}", method=requestmethod.put) public artist editartist(@modelattribute @valid artist artist, @pathvariable integer id, bindingresult result) { //if there's validation errors if (result.haserrors()) throw new invalidrequestexception("error updating artist", result); //call update service artist updatedartist; try { updatedartist = artistservice.update(artist); } catch (artistnotfoundexception e) { throw new resourcenotfoundexception("unable update artist id = "+ id +". no such artist exists."); } return updatedartist; } @requestmapping(value="/{id}", method=requestmethod.delete) public artist deleteartist(@pathvariable integer id) { //call delete service artist deletedartist; try { deletedartist = artistservice.delete(id); } catch (artistnotfoundexception e) { throw new resourcenotfoundexception("unable delete artist id = "+ id +". no such artist exists."); } return deletedartist; } }
artist.java:
@entity @table(name = "album") public class album implements serializable { private static final long serialversionuid = -4035577652644918231l; @id @generatedvalue(strategy=generationtype.auto) private int id; @column(name = "name") private string name; @column(name = "year") private int year; @manytoone(fetch=fetchtype.lazy) @joincolumn(name="artist_id", referencedcolumnname = "id", insertable = false, updatable = false) private artist artist; @column private int artist_id; @onetomany(mappedby="album", fetch=fetchtype.eager, orphanremoval=true) private list<song> songs; public int getid() { return id; } public void setid(int id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } public int getyear() { return year; } public void setyear(int year) { this.year = year; } public int getartist_id() { return artist_id; } public void setartist_id(int artist_id) { this.artist_id = artist_id; } public list<song> getsongs() { return songs; } public void setsongs(list<song> songs) { this.songs = songs; } }
initializer.java:
public class initializer implements webapplicationinitializer { private static final string dispatcher_servlet_name = "dispatcher"; public void onstartup(servletcontext servletcontext) throws servletexception { annotationconfigwebapplicationcontext ctx = new annotationconfigwebapplicationcontext(); ctx.register(webappconfig.class); servletcontext.addlistener(new contextloaderlistener(ctx)); ctx.setservletcontext(servletcontext); dynamic servlet = servletcontext.addservlet(dispatcher_servlet_name, new dispatcherservlet(ctx)); servlet.addmapping("/"); servlet.setloadonstartup(1); } }
webappconfig.java:
@configuration @enablewebmvc @enabletransactionmanagement @componentscan("com.project.jukebox") @propertysource("classpath:jdbc.properties") @enablejparepositories("com.project.jukebox.repositories") public class webappconfig extends webmvcconfigureradapter { private static final string property_name_database_driver = "jdbc.driver"; private static final string property_name_database_password = "jdbc.password"; private static final string property_name_database_url = "jdbc.url"; private static final string property_name_database_username = "jdbc.username"; private static final string property_name_hibernate_dialect = "hibernate.dialect"; private static final string property_name_hibernate_show_sql = "hibernate.show_sql"; private static final string property_name_entitymanager_packages_to_scan = "entitymanager.packages.to.scan"; @resource private environment env; @bean public datasource datasource() { drivermanagerdatasource datasource = new drivermanagerdatasource(); datasource.setdriverclassname(env.getrequiredproperty(property_name_database_driver)); datasource.seturl(env.getrequiredproperty(property_name_database_url)); datasource.setusername(env.getrequiredproperty(property_name_database_username)); datasource.setpassword(env.getrequiredproperty(property_name_database_password)); return datasource; } @bean public localcontainerentitymanagerfactorybean entitymanagerfactory() { localcontainerentitymanagerfactorybean entitymanagerfactorybean = new localcontainerentitymanagerfactorybean(); entitymanagerfactorybean.setdatasource(datasource()); entitymanagerfactorybean.setpersistenceproviderclass(hibernatepersistenceprovider.class); entitymanagerfactorybean.setpackagestoscan(env.getrequiredproperty(property_name_entitymanager_packages_to_scan)); entitymanagerfactorybean.setjpaproperties(hibproperties()); return entitymanagerfactorybean; } private properties hibproperties() { properties properties = new properties(); properties.put(property_name_hibernate_dialect, env.getrequiredproperty(property_name_hibernate_dialect)); properties.put(property_name_hibernate_show_sql, env.getrequiredproperty(property_name_hibernate_show_sql)); properties.put("hibernate.hbm2ddl.auto", "create-drop"); return properties; } @bean public jpatransactionmanager transactionmanager() { jpatransactionmanager transactionmanager = new jpatransactionmanager(); transactionmanager.setentitymanagerfactory(entitymanagerfactory().getobject()); return transactionmanager; } @bean public resourcebundlemessagesource messagesource() { resourcebundlemessagesource source = new resourcebundlemessagesource(); source.setbasename(env.getrequiredproperty("message.source.basename")); source.setusecodeasdefaultmessage(true); return source; } @bean public internalresourceviewresolver getinternalresourceviewresolver() { internalresourceviewresolver resolver = new internalresourceviewresolver(); resolver.setprefix("/web-inf/views/"); resolver.setsuffix(".jsp"); return resolver; } @override public void configuredefaultservlethandling(defaultservlethandlerconfigurer configurer) { configurer.enable(); } @bean public webcontentinterceptor webcontentinterceptor() { webcontentinterceptor interceptor = new webcontentinterceptor(); interceptor.setcacheseconds(0); interceptor.setuseexpiresheader(true); interceptor.setusecachecontrolheader(true); interceptor.setusecachecontrolnostore(true); return interceptor; } @override public void addresourcehandlers(resourcehandlerregistry registry) { registry.addresourcehandler("/resources/**").addresourcelocations("/resources/"); registry.addresourcehandler("/lib/**").addresourcelocations("/web-inf/lib/"); registry.addresourcehandler("/scripts/**").addresourcelocations("/web-inf/scripts/"); registry.addresourcehandler("/styles/**").addresourcelocations("/web-inf/styles/"); registry.addresourcehandler("/fonts/**").addresourcelocations("/web-inf/fonts/"); } @override public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(webcontentinterceptor()); } }
web.xml:
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>jukebox</display-name> <!-- filters needed put requests, known bug spring rest --> <filter> <filter-name>httpputformcontentfilter</filter-name> <filter-class>org.springframework.web.filter.httpputformcontentfilter</filter-class> </filter> <filter-mapping> <filter-name>httpputformcontentfilter</filter-name> <url-pattern>/*</url-pattern> <servlet-name>dispatcher</servlet-name> </filter-mapping> </web-app>
hard without seeing artist class, 400 bad request because of @valid annotation on artist in controller. validation checks if name not null, or params not null.
Comments
Post a Comment