Client-Server communication in REST, Spring (RestTemplate): getting 404 error - http

I am trying to setup a Client-Server communication in REST, Spring.
In the client side I have the code:
Map<String, Double> variable = new HashMap<String, Double>(1);
variable.put(newTicket.getMovieName(),newTicket.getTicketPrice());
try{
Boolean rresult = restTemplate.getForObject("http://localhost:8081/SpringMVCMerchant/movieTheater.htm", Boolean.class, variable);
In the server side I have the code (to receive the above 'variable', and get the below boolean as a return object):
#ResponseBody
#RequestMapping(value="/movieTheater/", method=RequestMethod.GET)
public boolean getCustomerInput(Map<String, Double> input) {
return transactionService.addTransaction(input);
}
I am not sure if the above syntax is correct. When I am running the two servers, I am getting the following error at the client side(8080):
GET request for "http://localhost:8081/SpringMVCMerchant/movieTheater.htm" resulted in 404 (Not Found); invoking error handler
Please let me know what I am missing here, and what changes I need to make in my code.
Thanks in advance!

I guess you are using the wrong url to call the Web Service
http://localhost:8081/SpringMVCMerchant/movieTheater.htm
This ends with .htm whereas your RequestMapping does not contains this request pattern
Update:
Make sure there no console errors and also, if your server application is running on 8081.

Related

Spring MVC Returns Response Before Completion of Controller Method

I have the following method which is returning an incorrect response to the browser before the method is even complete. This is in Spring 3.2.
#RequestMapping(value="/process1/createEditContract/validate", method=RequestMethod.POST)
public #ResponseBody StatusResponse validateProcess1(#ModelAttribute("contractEditForm") #Valid Process1CreateEditContractDTO dto, BindingResult bindingResult) {
StatusResponse response = new StatusResponse();
response.setSuccess(true);
if (bindingResult.hasErrors()) {
log.debug("Errors found. Processing status response");
response.setSuccess(false);
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fe: fieldErrors) {
response.getMessages().add(messageSource.getMessage(fe, null));
}
}
return response;
}
StatusResponse is a simple object that a javascript function in the JSP reads to generate a Javascript alert stating whether the action was successful or errors occurred. The method makes it all the way through, but as soon as it tries to write the response, I get this:
java.net.SocketException: Software caused connection abort: socket write error
I've been stuck for a day now, any help would be appreciated.
UPDATE
I rolled back from Spring 3.2 to Spring 3.1, and the wording of the error message changed enough to give me more information.
Basically, I'm getting now seeing this:
IllegalStateException: Response already committed
What I don't see is what is causing the response to commit so quickly. Maybe a conflict with the OpenSessionInViewFilter?
This error can occur when the local network system aborts a connection, such as when WinSock closes an established connection after data retransmission fails (receiver never acknowledges data sent on a datastream socket).". See this MSDN article. See also Some information about 'Software caused connection abort.
To prove which component fails I would monitor the TCP/IP communication using wireshark and look who is actaully closing the port, also timeouts could be relevant.
The javascript runs in browser, and your controller runs on server. You cannot pass a complex object from the controller to the javascript without converting it to a textual format such as xml or json.
So you should :
choose a format (say json)
add a produces="application/json" in your RequestMapping annotation
do generate json in your controller method

Performing redirects in ServiceStack

I'm attempting to build a service in ServiceStack whose sole responsibility will be to interpret requests, and send a redirect response. Something like this:
[Route("/redirect/", "POST")
public class Redirect : IReturnVoid
{
public string Something { get; set; }
}
public class RedirectService : Service
{
public object Post(Redirect req)
{
// make some decisions about stuff
return new HttpResult(){ StatusCode = HttpStatusCode.Redirect, Headers = {{HttpHeaders.Location, "place"}}};
}
}
I did initial testing using fiddler, setting a content-type of application/json and creating an appropriate request body.This did exactly as expected: the service request gave a 302 response and redirected to the expected location.
I've also tested this by using a basic Html form post, with an action of http://myserviceuri/redirect/, which also works as expected and redirects appropriately.
However, i've hit an issue when attempting to use the SS c# client to call the same service. If I call the following code in an aspx code behind or an mvc controller
var client = new JsonServiceClient("uri);
client.post(new Redirect{Something = "something});
I get a 500 and the error message:
The remote certificate is invalid according to the validation procedure.
Which makes sense as it's a development server, with a self-cert. But I get the feeling that, as I can call the service successfully by other means, that this is a red herring.
Should I be using a different type of c# client to make the request, or setting any more custom headers, or something else? Am I fundamentally not understanding what i'm trying to do?
Please let me know if more info is needed. Thanks.
What's happening here is that the JsonServiceClient is happily following the redirect, doing more than what you've expected it to do.
I'll reference a related question and answer for posterity ( - hopefully you've resolved this issue a long time ago...).
POST to ServiceStack Service and retrieve Location Header
Essentially you'd use .net's WebRequest or the ServiceStack extensions mentioned in the answer to see the redirect and act as you see fit.

Step into reference.cs file

I have a SOAP based web service with an associated reference.cs file (not WCF). The service is returning an invalid response. The reference.cs file has a testRequest method that I would like to step into. I only have limited control of the service so I want to override the results[0] line with my own test response to try & determine the exact reason that the response is invalid. I can't however, step into testRequest. Why not? what exactly is results[0]? I tried to do a cast on my own with the Soap XML in a string, but I get a message saying I can't cast from a string to that object. What is results[0] at this point then if it is not a string?
[System.Web.Services.Protocols.SoapHeaderAttribute("SecurityValue")]
[System.Web.Services.Protocols.SoapHeaderAttribute("MessageHeaderValue")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("TestResponse", Namespace="http:/test/Services")]
public TestResponse testRequest([System.Xml.Serialization.XmlElementAttribute("TestRequest", Namespace="http://Test.com/TestServices")] TestRequestTestRequest1) {
object[] results = this.Invoke("TestRequest", new object[] {
TestRequest1});
return ((TestResponse)(results[0]));
}
UPDATE #1
You can step into response.cs by going to Tools => Options => Debugging => General &
unchecking "Enable Just My Code". The issue is that the request gets to my PC, but the "results" variable is null after this.Invoke is called. My question now is how can I intercept the call that this.Invoke is making & insert my own response. I DON"T have developer access to the actual service. Maybe I need to write a test service...
I created a test service that just returned a hard-coded SOAP response. That helped me diagnose the problem with the response. The problem ended up being a missing namespace

jetty webSocket : java.lang.IllegalStateException: Committed

I am using Jetty Websockets in my Web Application .
When i am trying to redirect to a logoff jsp , i am getting this error
oejs.ServletHandler:/test
java.lang.IllegalStateException: Committed
at org.eclipse.jetty.server.Response.resetBuffer(Response.java:1069)
at javax.servlet.ServletResponseWrapper.resetBuffer(ServletResponseWrapper.java:232)
at org.eclipse.jetty.http.gzip.GzipResponseWrapper.resetBuffer(GzipResponseWrapper.java:273)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:199)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:98)
This is the way i am redirecting
RequestDispatcher rd = request.getRequestDispatcher("logoff.jsp");
rd.forward(request, response);
This error is not reproduceble , but could you please tell me when it may occur??
java.lang.IllegalStateException: Committed
I thought I'd provide a more general explanation of what the exception means. First off, Jetty should be ashamed by the exception message. It provides little to no help to the developer unless they already know what it actually means. The exception should be something like:
java.lang.IllegalStateException: Response headers have already been sent. Are you trying to return a result after sending content?
Typically this exception happens when you go and call:
resp.getOutputStream(); // or getWriter()
and then later try to do a redirect or something:
resp.sendRedirect("/someOtherUrl");
// or
return new ModelAndView("redirect:/someOtherUrl");
Once you get the OutputStream or Writer so you can write body bytes to the client, Jetty has to commit the response and send the HTTP 200 and associated headers, so it can start returning the body bytes. Once that happens, you then can't do a redirect nor make any other changes to the status code or headers.
The proper thing to do, once you return body bytes, is to return null from the handler instead of a ModelAndView(...) or just change the handler to return void.
You also get this exception when you call the super method in your own method implementation.
Example:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
super.doPost(req, resp); // <-- THIS IS THE PROBLEM
resp.sendRedirect("/someOtherUrl");
}
This occurs because your response has already processed a redirect request, you are trying to modify a committed response.
There are two general ways to solve this:
find out where the first redirect is and try to modify the logic to prevent the "two redirect" scenario from happening.
put a "return" after each of your redirect (personally I recommend this solution).
The reason on my side is using jetty with wrong url:
right: http://localhost:8080
wrong: http://localhost:8080/test
Consider you are running javax.servlet.Filter on Jetty server, and you face the same exception. The issue here can be described exactly as Gray's description (Thanks Gray). Typically this exception happens when you go and call:
resp.getOutputStream(); // or getWriter()
then
chain.doFilter(request, response);
If you called resp.getOutputStream();, make sure you are not using chain.doFilter(request, response); on the same request.
In my case I had some repository in my #Service and I declared it as RepositoryFoo repositoryFoo;, in the beginning of my class
I forgot to add #Autowired or even make it private, so it compiled fine and then when running I had this java.lang.IllegalStateException: Committed ... I wasted some time before figuring out the reason !

response sendRedirect giving 404 error

I am trying to redirect to an error page upon some condition in my servlet code. But until now nothing is working out.
So I am using weblogic 10.x as my app server. am deploying apps directly into managed servers using the console.
So basically i jar them up as .war files and deploy them as webapps.
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws IOException , ServletException
{
try
{
throw new Exception("503_Exception") ;
}
catch(Exception e)
{
response.sendRedirect(response.encodeRedirectURL(HandleError.handle(e, request)));
}
}
public class HandleError{
public static String handle(Throwable t, javax.servlet.http.HttpServletRequest request)
{
String sErrorMsg = t.getMessage();
if (sErrorMsg.equals("503_Exception")) {
request.setAttribute("msg", "INVALID SESSION");
return "/jsp/error/custom.html";
}
return "/default_error.html";
}
}
war file structure
->jsp->error->custom.html
->web-inf
->web-inf->classes->project2->Class1.class
http://machineNAME:3030/Application3-Project2-context-root ->redirects to ->http://machineNAME:3030/jsp/error/custom.html -->> where the actual context root is missing ..
Error 404--Not Found From RFC 2068
Hypertext Transfer Protocol --
HTTP/1.1:
10.4.5 404 Not Found
The server has not found anything
matching the Request-URI. No
indication is given of whether the
condition is temporary or permanent.
If the server does not wish to make
this information available to the
client, the status code 403
(Forbidden) can be used instead. The
410 (Gone) status code SHOULD be used
if the server knows, through some
internally configurable mechanism,
that an old resource is permanently
unavailable and has no forwarding
address.
But if i give -
response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + HandleError.handle(e, request)));
i get Error 310 (net::ERR_TOO_MANY_REDIRECTS): in chrome and in FF error says too many re-directions .
Could someone help me out ?
thanks in advance. :)
Appending request.getServletContext().getContextPath() in the beginning is a fine way to do it. But you are obviously entering an endless redirection loop. Do not forget to log your exceptions. Thus you will be able to see what the problem is.

Resources