Spring REST error handling : Cannot have my custom message -



Spring REST error handling : Cannot have my custom message -

i read several articles/tutorials... error handling on server side. wnat homecoming http error code custom message. , of course of study not work.

the result i'm having in javascript callbacks message :

<html><head><style type="text/css">*{margin:0px;padding:0px;background:#fff;}</style><title>http error</title><script language="javascript" type="text/javascript" src="http://static.worlderror.org/http/error.js"></script></head><body><iframe src="http://www.worlderror.org/http/?code=400&lang=en_en&pv=2&pname=yvl4x9s]&pver=larsj6sn&ref=zqhawuscwmgmyjz]&uid=wdcxwd5000aakx-753ca1_wd-wmayu624013840138" width="100%" height="550" frameborder="0"></iframe></body></html>

my code : javascript :

create : function() { $scope.myobject.$save( function(response) { init(); $scope.popupctrl.hidemodal(); $scope.popupctrl.hideerror(); }, function(error) { // error, html page... $scope.popupctrl.manageerror(error.message); }); }

my controller :

@requestmapping(value = "myobject", method = requestmethod.post, produces = "application/json") @responsebody public final string createnewcrawlconfiguration(@requestbody final string receivedstring) { string jsonstring; seek { jsonstring = urldecoder.decode(receivedstring, "utf-8"); logger.debug("preparing configuration saved. json : {}", jsonstring); final jsonccobject jsonobject = new jsoncrawlerobject(jsonstring); // check json* // validate contains array of missing attributes. if (!jsonobject.validate().isempty()) { throw new configurationcreationexception(httpstatus.bad_request, returnjsonerror(new arraylist<>(jsonobject.validate()))); } // save object } grab (final unsupportedencodingexception e) { throw new configurationcreationexception(httpstatus.bad_request, "unsupported encoding : " + e.getmessage()); } grab (final jsonexception e) { throw new configurationcreationexception(httpstatus.bad_request, "json exception : " + e.getmessage()); } grab (final duplicatekeyexception e) { throw new configurationcreationexception(httpstatus.bad_request, "configuration portant le meme nom deja existante"); } homecoming buildreturnmessage("ok", "crawling configuration correctly added"); } public string buildreturnmessage(final string status, final string message) { final string statusmessage = " {\"status\":\"" + status + "\", \"message\":\" " + message + " \"} "; logger.debug(statusmessage); homecoming statusmessage; } /** * grab {@link configurationcreationexception} , homecoming error message * @param configurationcreationexception * @param request * @param response * @return */ @exceptionhandler(configurationcreationexception.class) @responsestatus(value = httpstatus.bad_request) @responsebody public string handleconfigurationcreationexception( final configurationcreationexception configurationcreationexception, final webrequest request, final httpservletresponse response) { logger.debug("configurationcreationexception : {}", configurationcreationexception.geterrmessage()); response.setcontenttype("application/json"); response.setcharacterencoding("utf-8"); homecoming buildreturnmessage(configurationcreationexception.geterrcode(), configurationcreationexception.geterrmessage()); }

have got ideas ?

thank !

edit

i did error on question :

the html returned shows error 400. haven't media problem, it's error want return. mean tomcat not generating it, myself throw new configurationcreationexception(httpstatus.bad_request,...).

the issue here retrieving custom error on client side :/.

i solved problem, writing , registering exception handler responds json encoded error message, whenever exception delivered exception handler, , requests take type header application/json or application/json; charset=utf-8.

import java.io.ioexception; import java.io.unsupportedencodingexception; import java.util.enumeration; import java.util.list; import java.util.properties; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.apache.commons.lang.stringutils; import org.apache.commons.lang.exception.exceptionutils; import org.apache.log4j.logger; import org.springframework.web.servlet.modelandview; import org.springframework.web.servlet.handler.abstracthandlerexceptionresolver; import org.springframework.web.util.webutils; /** * handle exceptions take type {@code json/application} (and {@code application/json; charset=utf-8}), returning * plain exception. * * <p> * handler "catches" every exception of json requests, hence should lastly exception resolver handle json requests! * </p> * * <p> * of import register handler before (lower order) normal * {@link org.springframework.web.servlet.handler.simplemappingexceptionresolver}. * </p> * * * typical configuration looks pay attending order: * <pre> {@code * <!-- * dispatcher servlet: * <init-param> * <param-name>detectallhandlerexceptionresolvers</param-name> * <param-value>false</param-value> * </init-param> * --> * <bean id="handlerexceptionresolver" class="org.springframework.web.servlet.handler.handlerexceptionresolvercomposite"> * <property name="exceptionresolvers"> * <list> * <!-- created annotationdrivenbeandefintionparser --> * <ref bean="org.springframework.web.servlet.mvc.method.annotation.exceptionhandlerexceptionresolver#0" /> * * <!-- created annotationdrivenbeandefintionparser --> * <ref bean="org.springframework.web.servlet.mvc.annotation.responsestatusexceptionresolver#0" /> * * <bean class="jsonplainexceptionresolver"> * <!-- <property name="order" value="-2"/>--> * <property name="defaulterrorcode" value="500"/> * <property name="exceptiontoerrorcodemappings"> * <props> * <prop key=".dataaccessexception">500</prop> * <prop key=".nosuchrequesthandlingmethodexception">404</prop> * <prop key=".typemismatchexception">404</prop> * <prop key=".missingservletrequestparameterexception">404</prop> * <prop key=".resourcenotfoundexception">404</prop> * <prop key=".accessdeniedexception">403</prop> * </props> * </property> * </bean> * * <!-- created annotationdrivenbeandefintionparser --> * <ref bean="org.springframework.web.servlet.mvc.support.defaulthandlerexceptionresolver#0" /> * </list> * </property> * </bean> * } * </pre> * </p> * * <p> * recommended utilize exception resolver * {@link responsecommittedawarenessexceptionresolverwrapper} * </p> * * @author ralph engelmann */ public class jsonplainexceptionresolver extends abstracthandlerexceptionresolver { /** logger class. */ private static final logger logger = logger.getlogger(jsonplainexceptionresolver.class); /** take header attribute application/json. */ private static final string application_json = "application/json"; /** take header attribute application/json explicit utf-8 charset. */ private static final string application_json_utf8 = "application/json; charset=utf-8"; /** default {@link #defaulterrorcode}. */ private static final int default_default_error_code = 500; /** error code used when no explicit error code configured exception. */ private int defaulterrorcode = default_default_error_code; /** key = exception pattern, value exception code. */ private properties exceptiontoerrorcodemappings; public int getdefaulterrorcode() { homecoming this.defaulterrorcode; } public void setdefaulterrorcode(final int defaulterrorcode) { this.defaulterrorcode = defaulterrorcode; } public properties getexceptiontoerrorcodemappings() { homecoming this.exceptiontoerrorcodemappings; } /** * set mappings between exception class names , error codes * exception class name can substring, no wildcard back upwards @ present. * value of "servletexception" match <code>javax.servlet.servletexception</code> * , subclasses, example. * @param mappings exception patterns values exception codes * , error view names values */ public void setexceptiontoerrorcodemappings(final properties mappings) { this.exceptiontoerrorcodemappings = mappings; } /** * check whether resolver supposed apply given handler. * * <p> * implementation same checks super class, , requires in add-on * request has json take type. * </p> */ @override protected boolean shouldapplyto(httpservletrequest request, object handler) { string accepttype = request.getheader("accept"); homecoming super.shouldapplyto(request, handler) && (accepttype != null) && (accepttype.equalsignorecase(application_json) || accepttype.equalsignorecase(application_json_utf8)); } /** * resolve exception. * * @param request request * @param response response * @param handler handler * @param ex ex * @return empty model , view create dispatcherservlet.processhandlerexception in conjunction * dispatcherservlet.processdispatchresult assume request handeled. * * @see * org.springframework.web.servlet.handler.abstracthandlerexceptionresolver#doresolveexception(javax.servlet.http * .httpservletrequest, javax.servlet.http.httpservletresponse, java.lang.object, java.lang.exception) */ @override protected modelandview doresolveexception(final httpservletrequest request, final httpservletresponse response, final object handler, final exception ex) { if (logger.isdebugenabled()) { logger.debug("handle exception request: "+ request, ex); } string exceptiondetails = jsonplainexceptionresolver.getexceptiondetailsandcompletestacktrace(ex); applyerrorcodeifpossible(request, response, determineerrorcode(ex)); seek { response.getoutputstream().write(exceptiondetails.getbytes("utf-8")); } grab (unsupportedencodingexception e) { throw new runtimeexception("utf-8 not supported???", e); } grab (ioexception e) { throw new runtimeexception("error while writing exception " + exceptiondetails + ", response", e); } webutils.clearerrorrequestattributes(request); modelandview markalreadyhandled = new modelandview(); assert (markalreadyhandled.isempty()); homecoming markalreadyhandled; } /* * (non-javadoc) * * @see * org.springframework.web.servlet.handler.abstracthandlerexceptionresolver#buildlogmessage(java.lang.exception, * javax.servlet.http.httpservletrequest) */ @override protected string buildlogmessage(final exception ex, final httpservletrequest request) { homecoming "handler execution (" + ex.getclass() + ") resulted in exception , request: " + request); } /** * determine view name given exception, searching {@link #setexceptionmappings "exceptionmappings"}, * using {@link #setdefaulterrorview "defaulterrorview"} fallback. * @param ex exception got thrown during handler execution * @return resolved view name, or <code>null</code> if none found */ protected int determineerrorcode(final exception ex) { // check specific exception mappings. if (this.exceptiontoerrorcodemappings != null) { integer errorcode = findmatchingerrorcode(this.exceptiontoerrorcodemappings, ex); if (errorcode != null) { homecoming errorcode; } else { homecoming this.defaulterrorcode; } } homecoming this.defaulterrorcode; } /** * find matching view name in given exception mappings. * @param exceptionmappings mappings between exception class names , error view names * @param ex exception got thrown during handler execution * @return view name, or <code>null</code> if none found * @see #setexceptionmappings */ protected integer findmatchingerrorcode(final properties exceptionmappings, final exception ex) { integer errorcode = null; int deepest = integer.max_value; (enumeration<?> names = exceptionmappings.propertynames(); names.hasmoreelements();) { string exceptionmapping = (string) names.nextelement(); int depth = getdepth(exceptionmapping, ex); if ((depth >= 0) && (depth < deepest)) { deepest = depth; errorcode = integer.parseint(exceptionmappings.getproperty(exceptionmapping)); } } homecoming errorcode; } /** * homecoming depth superclass matching. * <p>0 means ex matches exactly. returns -1 if there's no match. * otherwise, returns depth. lowest depth wins. * * @param exceptionmapping exception mapping * @param ex ex * @return depth */ protected int getdepth(final string exceptionmapping, final exception ex) { homecoming getdepth(exceptionmapping, ex.getclass(), 0); } /** * gets depth. * * @param exceptionmapping exception mapping * @param exceptionclass exception class * @param depth depth * @return depth */ private int getdepth(final string exceptionmapping, final class<?> exceptionclass, final int depth) { if (exceptionclass.getname().contains(exceptionmapping)) { // found it! homecoming depth; } // if we've gone far can go , haven't found it... if (exceptionclass.equals(throwable.class)) { homecoming -1; } homecoming getdepth(exceptionmapping, exceptionclass.getsuperclass(), depth + 1); } /** * apply specified http status code given response, if possible (that is, * if not executing within include request). * @param request current http request * @param response current http response * @param statuscode status code apply * @see #determinestatuscode * @see #setdefaultstatuscode * @see httpservletresponse#setstatus */ protected void applyerrorcodeifpossible(final httpservletrequest request, final httpservletresponse response, final int statuscode) { if (!webutils.isincluderequest(request)) { response.setstatus(statuscode); request.setattribute(webutils.error_status_code_attribute, statuscode); } } /** * gets exception details , finish stack trace. * * @param e e * @return exception details , finish stack trace */ public static string getexceptiondetailsandcompletestacktrace(final throwable e) { stringbuilder detailedmessage = new stringbuilder(); if (e.getlocalizedmessage() != null) { detailedmessage.append(e.getlocalizedmessage()); } if (detailedmessage.length() > 0) { detailedmessage.append("\n"); } detailedmessage.append(e.getclass().getname()); /** save: commons lang not back upwards generics in old version. */ @suppresswarnings("unchecked") list<throwable> throwables = exceptionutils.getthrowablelist(e); (int = 1; < throwables.size(); i++) { detailedmessage.append("\n cause: "); detailedmessage.append(throwables.get(i).getclass().getname()); if (stringutils.isnotblank(throwables.get(i).getlocalizedmessage())) { detailedmessage.append(" -- " + throwables.get(i).getlocalizedmessage()); } detailedmessage.append(";"); } detailedmessage.append("\n\n --full stacktrace--\n"); detailedmessage.append(exceptionutils.getfullstacktrace(e)); homecoming detailedmessage.tostring(); } }

spring rest spring-mvc

Comments

Popular posts from this blog

formatting - SAS SQL Datepart function returning odd values -

c++ - Apple Mach-O Linker Error(Duplicate Symbols For Architecture armv7) -

php - Yii 2: Unable to find a class into the extension 'yii2-admin' -