WCF call via MSMQ erratic - asp.net

The code is trivial so rather than explain, here's the relevant portion:
protected void Page_Load(object sender, EventArgs e)
{
if ((Request.HttpMethod == "POST") && (Request.ContentType == "text/xml"))
{
string filename = string.Format("{0:yyyyMMddHHmmss}.xml", DateTime.UtcNow);
var path = Path.Combine(Request.MapPath("Chapters"), Request.Headers["X-MAC"]);
Directory.CreateDirectory(path);
string xml;
using (ChapterWriterClient client = new ChapterWriterClient())
using (StreamReader sr = new StreamReader(Request.InputStream))
{
xml = sr.ReadToEnd();
client.Write(xml);
System.Diagnostics.Trace.TraceInformation(xml);
}
Request.SaveAs(Path.Combine(path, filename), false);
}
There's more but the rest of it works as expected.
Here's the problem: the call client.Write(string xml) is erratic in whether it succeeds.
Some known facts:
No error is ever reported to the debugger or the event log
Sometimes the XML makes it into the message queue and sometimes it doesn't
Request.SaveAs(string filepath, bool includeHeaders) call always succeeds and the resultant file always contains the expected XML. This has several important implications:
The call to WCF is being executed.
Because the string xml had the expected value immediately after the failed WCF call, and assignment to this variable occurs only prior to the WCF call, it must have had the correct value at the time of the call.
There is some variation in message size so I'm checking the service config in that regard but past experience tells me to expect an exception thrown when the payload is too big.
Any clues would be appreciated.
Also, as you can probably see the whole point of the exercise is a somewhat naiive attempt to use an HTTP POST to put some XML into a message on MSMQ. I'd be perfectly happy with a "Don't do it like that, do it like this you ignorant savage" type answer.

Related

BizTalk - Fail to Promote Properties

Using BizTalk 2013r2 CU1, I have a created a property schema for my inbound xsd and deployed the application.
When I receive a sample xml document using a standard "xml receive" pipeline then I can see that the required element is promoted into the context as expected.
I then created a custom pipeline which contains the "XML disassembler" component in the "Disassemble" stage and a custom component in the "Validate" stage. This custom component needs to read the promoted property from the context. However, I find that when I switch the Receive Location from "xml receive" pipeline to my custom pipeline then my property does not get promoted. I am using the following code within my custom component to write out a list of items in the message context:
for (int x = 0; x < contextList.CountProperties; x++)
{
contextList.ReadAt(x, out name, out nspace);
string value = contextList.Read(name, nspace).ToString();
contextItems += "Name: " + name + " - " + "Namespace: " + nspace + " - " + value + "\r\n";
if (name == _ContextPropertyName && nspace == _ContextPropertyNamespace)
promotedPropFound = true;
}
Helpers.EventLogHelper eventHelper = new EventLogHelper();
eventHelper.LogEvent(string.Format("Context items:{0}", contextItems));
if (promotedPropFound == false)
throw new Exception(string.Format("Unable to find promoted property with name[{0}] and namespace [{1}]", _ContextPropertyName, _ContextPropertyNamespace));
From the output in the event log I can see that certain properties such as MessageType have been promoted but my custom property has not. Again, if I change the receive location back to use a standard "xml receive" pipeline then the property will be promoted from a copy of the same xml document (I check this by stopping the subscribing send port and viewing the context from the admin console).
I find this very strange since the same "XML disassembler" component is present in the same "Disassemble" stage of both pipelines, with the same (default)configuration. I'm starting to think perhaps there's a problem with 2013r2CU1 - has anyone else encountered the same?
By the time the XML Disassembler has executed in your custom pipeline, there is no guarantee that your properties have been promoted.
The incoming message arrives in the pipeline as a stream with the data pointer set at the start of the stream.
I think the XML Disassembler does not read the stream, it wraps it into some stream wrapper class that will populate the promoted properties when the stream actually gets read.
The stream will have to be read at least once: when the message gets inserted into the message box. So there is a guarantee that the properties will get promoted, but you cannot assume it will be done before the "Validate" stage executes.
To make sure this is really the problem your are encountering: check your message AFTER it has been imported into the message box.
If your promoted property is there, what I described is probably what is happening.
Solutions:
To make your custom pipeline component work, the best solution would be to do just as the XML Disassembler: get the incoming stream and wrap it into a stream wrapper class that can trigger whatever functionality you need.
The assembly Microsoft.BizTalk.Streaming.dll has some wrapper class that might interest you: ForwardOnlyEventingReadStream.
This class has an event AfterLastReadEvent. You can create some EventHandler and have it subscribe to this event to trigger your custom functionality only after the stream has been fully read., and all properties have been promoted.
Your custom component would look like that:
public IBaseMessage Execute(IPipelineContext context, IBaseMessage message)
{
Stream stream = message.BodyPart.GetOriginalDataStream();
CForwardOnlyEventingReadStream eventingReadStream = new CForwardOnlyEventingReadStream(stream);
eventingReadStream.AfterLastReadEvent += new AfterLastReadEventHandler(DoSomething);
message.BodyPart.Data = eventingReadStream;
return message;
}
private static void DoSomething(object src, EventArgs args)
{
}
A less efficient way to solve your problem would be to read the stream fully in your custom component at the "Validate" stage and put the stream pointer back to the start of the stream.
Microsoft has some guidelines for when you're manipulating the message stream in pipeline component:
https://msdn.microsoft.com/en-us/library/aa577699.aspx
Update:
OP needs to pass the message context to the Event Handler.
It is possible using a Lambda expression:
public IBaseMessage Execute(IPipelineContext context, IBaseMessage message)
{
Stream stream = message.BodyPart.GetOriginalDataStream();
CForwardOnlyEventingReadStream eventingReadStream = new CForwardOnlyEventingReadStream(stream);
eventingReadStream.AfterLastReadEvent += new AfterLastReadEventHandler((src, args) => DoSomething(src, args, message.Context));
message.BodyPart.Data = eventingReadStream;
return message;
}
private static void DoSomething(object src, EventArgs args, IBaseMessageContext messageContext)
{
}
This SO question can be interesting for reference for passing the additional parameter:
Pass parameter to EventHandler
Can you do whatever you had planned for the Validate Stage in an Orchestration? That would be much easier.
If not, the most common solution to this specific problem is an intermediate Pipeline Component that forces a full read on the stream, though technically, you'd only have to read until the Promoted node is hit.

Is ReleaseRequestState called multiple times for each Request received by IIS?

I am writing an HttpModule in VS2010/ASP.NET 4.0 for use with IIS 7. The module is going to enforce query string security by encrypting query strings.
I would like this module to be completely independent of as well as transparent to the website, so that the website has no knowledge of the fact that query string encryption is being employed. This will ensure firstly that pages/controls don't have to care about this issue. Secondly, it would enable query string encryption for Production environments and disable it for non-Production ones (by removing the HTTP module from the Web.config).
I have designed the HttpModule to get plugged into IIS via the Web.config by:
<configuration>
<system.web>
<httpModules>
<add name="QueryStringSecurityModule" type="MyHttpModules.QueryStringSecurityModule"/>
</httpModules>
</system.web>
</configuration>
The module itself looks like this:
public class QueryStringSecurityModule : IHttpModule
{
public virtual void Init(HttpApplication application)
{
application.BeginRequest += HandleBeginRequest;
application.EndRequest += HandleEndRequest;
application.ReleaseRequestState += HandleReleaseRequestState;
}
public virtual void Dispose()
{
}
private void HandleBeginRequest(object sender, EventArgs e)
{
// TODO : Decrypt the query string here and pass it on to the application
}
private void HandleEndRequest(object sender, EventArgs e)
{
// TODO : Twiddle thumbs
}
private void HandleReleaseRequestState(object sender, EventArgs e)
{
var response = HttpContext.Current.Response;
if (response.ContentType == "text/html")
{
response.Filter = new QueryStringSecurityStream(response.Filter);
}
}
}
There is a class QueryStringSecurityStream which is used to fiddle with the HTML output in the Response, and secure all tags by replacing the query strings therein with encrypted ones.
public QueryStringSecurityStream : Stream
{
public QueryStringSecurityStream(Stream stream)
: base()
{
}
public override void Write(byte[] buffer, int offset, int count)
{
var html = Encoding.Default.GetString(buffer, offset, count).ReplaceHRefsWithSecureHRefs();
var bytes = Encoding.Default.GetBytes(html);
this.stream.Write(bytes, 0, bytes.Length);
}
}
The magic happens, or is supposed to happen, in the ReplaceHRefsWithSecureHRefs() extension method.
This method expects the entire HTML. It will go through it with a fine-toothed comb (i.e., using a Regex), find all the anchor tags, take out their href attributes, replace any query strings in the href value with encrypted versions and return the HTML. This HTML will then be written out to the Response stream.
So far so good. All of this falls over because I suspect that ReleaseRequestState is raised multiple times for individual requests. That is to say, that there are multiple calls to ReleaseRequestState as a result of a single call to BeginRequest.
What I am looking for is:
Confirmation that my hunch is correct. I have asked Mr. Google and Mr. MSDN but haven't found anything definitive. I seem to remember hitting something similar while debugging WSDL from an ASMX web service running in IIS 6. In that case I solved the issue by caching the incoming byte stream till I have valid XML and then writing it all out after modifying it.
The right way to handle this sort of scenario. You can take this to either mean specifically the single BeginRequest/multiple ReleaseRequestState calls issue or query string encryption generally.
Ladies and Gentlemen. Start your engines. Let the answers roll in.
Update:
I read this article on MSDN on request life-cycle
I have solved this issue for myself by creating a buffer to store response content across multiple calls to ReleaseRequestState. On every call, I check for the existence of a </html> tag and writes out the content buffered up to that point after modification (in my case encrypting the query strings in the <a> tags).
So:
Declare a StringBuilder as a private field member in the QueryStringSecurityModule class (in my case a StringBuilder to serve as a buffer for response content).
Initialize the field at BeginRequest (in my case, allocate a StringBuilder).
Finalize the field at EndRequest (in my case set it to null, though I have read that EndRequest doesn't always fire)
Buffer bytes being sent to Write in the custom filter till we find a closing html tag, at which point we modify buffer contents and write them out to the output stream.
Would anybody like to comment on this approach?

Problem with dotnetopenauth client.ProcessUserAuthorization()

I downloaded DotNetOpenAuth-3.5.0.10259 and tried to run the samples, specifically the OAuthClient sample and I managed to get it to work with facebook (VS2010). I can see "Welcome, [my name]" after allowing access in facebook.
The problem comes in when I try to use it in another project. I get a "No overload for method 'ProcessUserAuthorization' takes '0' arguments" and "No overload for method 'RequestUserAuthorization' takes '0' arguments".
Its basically the same code, which I find very weird since it works on the included sample but won't compile in the other project.
What did I miss?
protected void Page_Load(object sender, EventArgs e)
{
IAuthorizationState authorization = client.ProcessUserAuthorization();
if (authorization == null)
{
// Kick off authorization request
client.RequestUserAuthorization();
}
private static readonly FacebookClient client = new FacebookClient
{
ClientIdentifier = ConfigurationManager.AppSettings["facebookAppID"],
ClientSecret = ConfigurationManager.AppSettings["facebookAppSecret"],
};
The FacebookClient class came from the DotNetOpenAuth.ApplicationBlock project in the samples included in the 3.5.0.10259 download.
The only thing I can guess is that there is missing overload definitions within the libraries. I experienced the same issue you are describing, but in my case I couldn't get the samples to compile at all.
The trick though, is to simply pass in a NULL for the request parameter, which seems to work:
IAuthorizationState authorization = client.ProcessUserAuthorization(null);
Also note that you may run into the same missing overload issue with the "RequestUserAuthorization" method. Likewise, you can also pass in null values for each of the three parameters if you don't want to send them along:
client.RequestUserAuthorization(null, null, null);
Good luck!

IHttpModule.BeginRequest firing 2X, Application_BeginRequest firing 1X

I'm running VS 2008 and .NET 3.5 SP1.
I want to implement hit tracking in an HttpModule in my ASP.NET app. Pretty simple, I thought. However, the BeginRequest event of my HttpModule is firing twice for each page hit. The site is very simple right now...no security, just a bit of database work. Should log one row per page hit. Why is this event firing twice?
Moreover, IHttpModule.BeginRequest actually fires a different number of times for the first page hit when running for the first time (from a closed web browser)...3 times when I'm hitting the DB to provide dynamic data for the page, and only 1 time for pages where the DB isn't hit. It fires 2 times for every page hit after the first one, regardless of whether or not I'm touching the DB.
It's interesting to note that Application_BeginRequest (in Global.asax) is always firing only once.
Here's the code:
using System;
using System.Data;
using System.Data.Common;
using System.Net;
using System.Web;
using BluHeron.BusinessLayer;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
namespace BluHeron.HttpModules
{
public class SiteUsageModule : IHttpModule
{
public void Init(HttpApplication httpApp)
{
httpApp.BeginRequest += OnBeginRequest;
}
static void OnBeginRequest(object sender, EventArgs a)
{
UsageLogger.LogSiteUsage(((HttpApplication)sender).Context.Request);
}
public void Dispose()
{ }
}
public static class UsageLogger
{
public static void LogSiteUsage(HttpRequest r)
{
string ipAddress = GetHostAddress(Dns.GetHostAddresses(Dns.GetHostName()));
string browserVersion = r.Browser.Type;
string[] urlChunks = r.RawUrl.Split('/');
string page = urlChunks[urlChunks.GetLength(0)-1];
SqlDatabase db = new SqlDatabase(Common.GetConnectionString());
DbCommand cmd = db.GetStoredProcCommand("LogUsage");
db.AddInParameter(cmd, "IPAddress", SqlDbType.NVarChar, ipAddress);
db.AddInParameter(cmd, "BrowserVersion", SqlDbType.NVarChar, browserVersion);
db.AddInParameter(cmd, "PageName", SqlDbType.NVarChar, page);
db.AddInParameter(cmd, "Notes", SqlDbType.NVarChar, "");
db.ExecuteNonQuery(cmd);
}
private static string GetHostAddress(IPAddress[] addresses)
{
foreach (IPAddress ip in addresses)
{
if (ip.ToString().Length <= 15)
{
return ip.ToString();
}
}
return "";
}
}
}
This might be too late for the answer but can be useful for someone else. I faced with the same problem. BeginRequest event triggered for twice for each request. I debugged the code and realized that the first trigger for actual resource request but the second is result of "favicon.ico" request. At the beginning of BeginRequest event, a simple check for favicon.ico request eliminates second execution of the method.
public void Application_BeginRequest(object sender, EventArgs e) {
HttpApplication app = (HttpApplication)sender;
HttpContext ctx = app.Context;
if (ctx.Request.Path == "/favicon.ico") { return; }
quite late on this, but ran into the same issue. In our case it was due to the anonymous request first that returns the 401 per the RFC. The second request authenticates.
The "Default Document" part of IIS seems to fire a second BeginRequest event.
If you have determined that the Request.Path is the same for the HttpApplication in both event handlers and your URL ends with a slash, try adding a URL Rewrite rule to shortcut the "Default Document" processing.
This is interesting. I removed the reference to the CSS file from the master page and I'm getting fewer repeat hits in the HttpModule for certain browsers (as was suggested), but I'm still getting repeats. I have 6 browsers installed, and I'm getting some variation between them.
For reference, this is the URL I'm plugging in to my browsers for this test:
http://localhost/BluHeron
default.aspx is set as the start page and is indeed returned for the aforementioned URL. I'm using HttpRequest.RawUrl for reporting which page the user hit. Specifically, I'm splitting the RawUrl string and just reporting the last item in the array of strings (see code).
Every single browser is reporting hitting default.aspx, as expected (RawUrl = /BluHeron/default.aspx).
4 of the 6 browsers are also reporting BluHeron (RawUrl = /BluHeron).
3 of the 6 browsers are also recording a blank in the database (RawUrl = /BluHeron/).
There are a couple ways I can get accurate reporting of how many people are hitting which pages.
Select from the database only rows that actually list one of my pages (ignore /BluHeron and blanks)
Just use Application_BeginRequest in the global.asax file, which seems to consistently get called only once per page hit.
Get this figured out.
So, I've got options for getting good reports even with crappy data in the database. I would prefer to understand what's going on here and not to have junk in the database.
Thanks for looking, everyone!
We solved this by using
HttpContext.Current.ApplicationInstance.CompleteRequest();
This should prevent the the twice fire you are seeing.
One possibility is that there are other requests going on that you might not be considering. For example, let's say your ASPX page references some images or CSS files. If those requests go through the ASP.NET pipeline then your module will be called and they'll register as hits.
Also, when you say IHttpModule.BeginRequest, do you mean that in IHttpModule.Init() you are hooking up HttpApplication.BeginRequest? If so then the reason I mention above might still apply.
Disable Browser Link in Visual Studio 2013 and up, which causes the second request.
This occurs when an Application is run from Visual Studio.

java.lang.IllegalStateException: Cannot (forward | sendRedirect | create session) after response has been committed

This method throws
java.lang.IllegalStateException: Cannot forward after response has been committed
and I am unable to spot the problem. Any help?
int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
String chkboxVal = "";
// String FormatId=null;
Vector vRow = new Vector();
Vector vRow1 = new Vector();
String GroupId = "";
String GroupDesc = "";
for (int i = 0; i < noOfRows; i++) {
if ((request.getParameter("chk_select" + i)) == null) {
chkboxVal = "notticked";
} else {
chkboxVal = request.getParameter("chk_select" + i);
if (chkboxVal.equals("ticked")) {
fwdurl = "true";
Statement st1 = con.createStatement();
GroupId = request.getParameter("GroupId" + i);
GroupDesc = request.getParameter("GroupDesc" + i);
ResultSet rs1 = st1
.executeQuery("select FileId,Description from cs2k_Files "
+ " where FileId like 'M%' and co_code = "
+ ccode);
ResultSetMetaData rsm = rs1.getMetaData();
int cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol1 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol1.addElement(rs1.getObject(j));
}
vRow.addElement(vCol1);
}
rs1 = st1
.executeQuery("select FileId,NotAllowed from cs2kGroupSub "
+ " where FileId like 'M%' and GroupId = '"
+ GroupId + "'" + " and co_code = " + ccode);
rsm = rs1.getMetaData();
cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol2 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol2.addElement(rs1.getObject(j));
}
vRow1.addElement(vCol2);
}
// throw new Exception("test");
break;
}
}
}
if (fwdurl.equals("true")) {
// throw new Exception("test");
// response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
request.setAttribute("GroupId", GroupId);
request.setAttribute("GroupDesc", GroupDesc);
request.setAttribute("vRow", vRow);
request.setAttribute("vRow1", vRow1);
getServletConfig().getServletContext().getRequestDispatcher(
"/GroupCopiedUpdt.jsp").forward(request, response);
}
forward/sendRedirect/sendError do NOT exit the method!
A common misunderstanding among starters is that they think that the call of a forward(), sendRedirect(), or sendError() would magically exit and "jump" out of the method block, hereby ignoring the remnant of the code. For example:
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!
}
This is thus actually not true. They do certainly not behave differently than any other Java methods (expect of System#exit() of course). When the someCondition in above example is true and you're thus calling forward() after sendRedirect() or sendError() on the same request/response, then the chance is big that you will get the exception:
java.lang.IllegalStateException: Cannot forward after response has been committed
If the if statement calls a forward() and you're afterwards calling sendRedirect() or sendError(), then below exception will be thrown:
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
To fix this, you need either to add a return; statement afterwards
protected void doXxx() {
if (someCondition) {
sendRedirect();
return;
}
forward();
}
... or to introduce an else block.
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
else {
forward();
}
}
To naildown the root cause in your code, just search for any line which calls a forward(), sendRedirect() or sendError() without exiting the method block or skipping the remnant of the code. This can be inside the same servlet before the particular code line, but also in any servlet or filter which was been called before the particular servlet.
In case of sendError(), if your sole purpose is to set the response status, use setStatus() instead.
Do not write any string before forward/sendRedirect/sendError
Another probable cause is that the servlet writes to the response while a forward() will be called, or has been called in the very same method.
protected void doXxx() {
out.write("<p>some html</p>");
// ...
forward(); // Fail!
}
The response buffer size defaults in most server to 2KB, so if you write more than 2KB to it, then it will be committed and forward() will fail the same way:
java.lang.IllegalStateException: Cannot forward after response has been committed
Solution is obvious, just don't write to the response in the servlet. That's the responsibility of the JSP. You just set a request attribute like so request.setAttribute("data", "some string") and then print it in JSP like so ${data}. See also our Servlets wiki page to learn how to use Servlets the right way.
Do not write any file before forward/sendRedirect/sendError
Another probable cause is that the servlet writes a file download to the response after which e.g. a forward() is called.
protected void doXxx() {
out.write(bytes);
// ...
forward(); // Fail!
}
This is technically not possible. You need to remove the forward() call. The enduser will stay on the currently opened page. If you actually intend to change the page after a file download, then you need to move the file download logic to page load of the target page. Basically: first create a temporary file on disk using the way mentioned in this answer How to save generated file temporarily in servlet based web application, then send a redirect with the file name/identifier as request param, and in the target page conditionally print based on the presence of that request param a <script>window.location='...';</script> which immediately downloads the temporary file via one of the ways mentioned in this answer Simplest way to serve static data from outside the application server in a Java web application.
Do not call forward/sendRedirect/sendError in JSP
Yet another probable cause is that the forward(), sendRedirect() or sendError() methods are invoked via Java code embedded in a JSP file in form of old fashioned way <% scriptlets %>, a practice which was officially discouraged since 2003. For example:
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<% sendRedirect(); %>
...
</body>
</html>
The problem here is that JSP internally immediately writes template text (i.e. HTML code) via out.write("<!DOCTYPE html> ... etc ...") as soon as it's encountered. This is thus essentially the same problem as explained in previous section.
Solution is obvious, just don't write Java code in a JSP file. That's the responsibility of a normal Java class such as a Servlet or a Filter. See also our Servlets wiki page to learn how to use Servlets the right way.
See also:
What exactly does "Response already committed" mean? How to handle exceptions then?
Unrelated to your concrete problem, your JDBC code is leaking resources. Fix that as well. For hints, see also How often should Connection, Statement and ResultSet be closed in JDBC?
even adding a return statement brings up this exception, for which only solution is this code:
if(!response.isCommitted())
// Place another redirection
Typically you see this error after you have already done a redirect and then try to output some more data to the output stream. In the cases where I have seen this in the past, it is often one of the filters that is trying to redirect the page, and then still forwards through to the servlet. I cannot see anything immediately wrong with the servlet, so you might want to try having a look at any filters that you have in place as well.
Edit: Some more help in diagnosing the problem…
The first step to diagnosing this problem is to ascertain exactly where the exception is being thrown. We are assuming that it is being thrown by the line
getServletConfig().getServletContext()
.getRequestDispatcher("/GroupCopiedUpdt.jsp")
.forward(request, response);
But you might find that it is being thrown later in the code, where you are trying to output to the output stream after you have tried to do the forward. If it is coming from the above line, then it means that somewhere before this line you have either:
output data to the output stream, or
done another redirect beforehand.
Good luck!
You should add return statement while you are forwarding or redirecting the flow.
Example:
if forwardind,
request.getRequestDispatcher("/abs.jsp").forward(request, response);
return;
if redirecting,
response.sendRedirect(roundTripURI);
return;
This is because your servlet is trying to access a request object which is no more exist..
A servlet's forward or include statement does not stop execution of method block. It continues to the end of method block or first return statement just like any other java method.
The best way to resolve this problem just set the page (where you suppose to forward the request) dynamically according your logic. That is:
protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
returnPage="page1.jsp";
}
if(condition2){
returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}
and do the forward only once at last line...
you can also fix this problem using return statement after each forward() or put each forward() in if...else block
I removed
super.service(req, res);
Then it worked fine for me
Bump...
I just had the same error. I noticed that I was invoking super.doPost(request, response); when overriding the doPost() method as well as explicitly invoking the superclass constructor
public ScheduleServlet() {
super();
// TODO Auto-generated constructor stub
}
As soon as I commented out the super.doPost(request, response); from within doPost() statement it worked perfectly...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//super.doPost(request, response);
// More code here...
}
Needless to say, I need to re-read on super() best practices :p
After return forward method you can simply do this:
return null;
It will break the current scope.
If you see this on a Spring based web application, make sure you have your method annotated with #ResponseBody or the controller annotated with #RestController instead of #Controller. It will also throw this exception if a method returns JSON, but has not been configured to have that as the response, Spring will instead look for a jsp page to render and throw this exception.

Resources