Java EE put execution - servlets

I am solving a task connected with servlets. Everything is in doPut method extended HttpServlet. Recommendation is called:
,,To set a variable user executes PUT request to /calc/<variable_name> URI where <variable_name> is a variable name (latin lowercase single characters) and variable value is the request body''.
I have no idea how to send above request. I tried something like but it fails
http.setEntity(new StringEntity(here variable))
HttpResponse response1 = httpclient.execute(httpPut);
In this case I get
Servlet.service() for servlet [VariablesCalculator] in context with path [] threw exception.
I will be thankful for your responses

Related

Is there a way to intercept RPC calls to UNIMPLEMENTED RPC

I made a change to the .proto file where the path of a method changed
old .proto
package foo
rpc test
Method path is foo.test
new .proto
package foo.v1
rpc test
Method path is foo.v1.test
Of course, old clients will stop working with error
12 UNIMPLEMENTED: unknown service foo.test
I don't want to version my APIs instead I want to run a server interceptor that fixes the path for each incoming request.
The issue is the client gets an error response UNIMPLEMENTED before the request is handled by the interceptor.
To my understanding, the interceptor function is executed before the handler but, it seems there is code running that check the connection and the method name before the interceptor.
My question is how to get the server interceptor to run first and change the method path?
Ps. the cleint uses grpc-js
The method path can't be changed after call method. The interceptor execute later than find method by service and method name. So you should not remove the origin method when any client still call this method.

What is the complete lifecycle of an OData controller http request in WebApi 2

I wonder what is the full lifecycle of an odata http request over an ODataController hosted in IIS.
For instance:
What are the IIS pipelining steps ?
How is the request handled when entering the ASP.NET controllers area ?
When routing is applied ?
When the Attributes such HttpPost, ApplyFilter are applied ?
Maybe this thread can help you:
The ASP.NET Web API 2 HTTP Message Lifecycle in 43 Easy Steps
It all starts with IIS:
IIS (or OWIN self-hosting) receives a request.
The request is then passed to an instance of HttpServer.
HttpServer is responsible for dispatching HttpRequestMessage objects.
HttpRequestMessage provides strongly-typed access to the request.
If one or more global instances of DelegatingHandler exist on the pipeline, the request is passed to it. The request arrives at the instances of DelegatingHandler in the order said instances were added to the pipeline.
DelegatingHandler instances can skip the remainder of the pipeline and create their own response. I do exactly this in my Custom Validation with FluentValidation post.
If the HttpRequestMessage passes the DelegatingHandler instances (or no such handler exists), then the request proceeds to the HttpRoutingDispatcher instance.
HttpRoutingDispatcher chooses which routing handler to call based on the matching route. If no such route exists (e.g. Route.Handler is null, as seen in the diagram) then the request proceeds directly to Step 10.
If a Route Handler exists for the given route, the HttpRequestMessage is sent to that handler.
It is possible to have instances of DelegatingHandler attached to individual routes. If such handlers exist, the request goes to them (in the order they were added to the pipeline).
An instance of HttpMessageHandler then handles the request. If you provide a custom HttpMessageHandler, said handler can optionally return the request to the "main" path or to a custom end point.
The request is received by an instance of HttpControllerDispatcher, which will route the request to the appropriate route as determined by the request's URL.
The HttpControllerDispatcher selects the appropriate controller to route the request to.
An instance of IHttpControllerSelector selects the appropriate HttpControllerDescriptor for the given HttpMessage.
The IHttpControllerSelector calls an instance of IHttpControllerTypeResolver, which will finally call...
an instance of IAssembliesResolver, which ultimately selects the appropriate controller and returns it to the HttpControllerDispatcher from Step 11.
NOTE: If you implement Dependency Injection, the IAssembliesResolver will be replaced by whatever container you register.
Once the HttpControllerDispatcher has a reference to the appropriate controller, it calls the Create() method on an IHttpControllerActivator...
which creates the actual controller and returns it to the Dispatcher. The dispatcher then sends the request into the Select Controller Action routine, as shown below.
We now have an instance of ApiController which represents the actual controller class the request is routed to. Said instance calls the SelectAction() method on IHttpActionSelector...
Which returns an instance of HttpActionDescriptor representing the action that needs to be called.
Once the pipeline has determined which action to route the request to, it executes any Authentication Filters which are inserted into the pipeline (either globally or local to the invoked action).
These filters allow you to authenticate requests to either individual actions, entire controllers, or globally throughout the application. Any filters which exist are executed in the order they are added to the pipeline (global filters first, then controller-level filters, then action-level filters).
The request then proceeds to the [Authorization Filters] layer, where any Authorization Filters which exist are applied to the request.
Authorization Filters can optionally create their own response and send that back, rather than allowing the request to proceed through the pipeline. These filters are applied in the same manner as Authentication Filters (globally, controller-level, action-level). Note that Authorization Filters can only be used on the Request, not the Response, as it is assumed that if a Response exists, the user had the authorization to generate it.
The request now enters the Model Binding process, which is shown in the next part of the main poster. Each parameter needed by the action can be bound to its value by one of three separate paths. Which path the binding system uses depends on where the value needed exists within the request.
If data needed for an action parameter value exists in the entity body, Web API reads the body of the request; an instance of FormatterParameterBinding will invoke the appropriate formatter classes...
which bind the values to a media type (using MediaTypeFormatter)...
which results in a new complex type.
If data needed for a parameter value exists in the URL or query string, said URL is passed into an instance of IModelBinder, which uses an IValueProvider to map values to a model (see Phil Haack's post about this topic for more info)....
which results in a simple type.
If a custom HttpParameterBinding exists, the system uses that custom binding to build the value...
which results in any kind (simple or complex) of object being mappable (see Mike Stall's wonderful series on this topic).
Now that the request is bound to a model, it is passed through any Action Filters which may exist in the pipeline (either globally or just for the action being invoked).
Once the action filters are passed, the action itself is invoked, and the system waits for a response from it.
If the action produces an exception AND an exception filter exists, the exception filter receives and processes the exception.
If no exception occurred, the action produces an instance of HttpResponseMessage by running the Result Conversion subroutine, shown in the next screenshot.
If the return type is already an HttpResponseMessage, we don't need to do any conversion, so pass the return on through.
If the return type is void, .NET will return an HttpResponseMessage with the status 204 No Content.
If the return type is an IHttpActionResult, call the method ExecuteAsync to create an HttpResponseMessage.
In any Web API method in which you use return Ok(); or return BadRequest(); or something similar, that return statement follows this process, rather than any of the other processes, since the return type of those actions is IHttpActionResult.
For all other types, .NET will create an HttpResponseMessage and place the serialized value of the return in the body of that message.
Once the HttpResponseMessage has been created, return it to the main pipeline.
Pass the newly-created HttpResponseMessage through any AuthenticationFilters which may exist.
The HttpResponseMessage flows through the HttpControllerDispatcher, which at this point probably won't do anything with it.
The Response also flows through the HttpRoutingDispatcher, which again won't do anything with it.
The Response now proceeds through any DelegatingHandlers that are set up to handle it. At this point, the DelegatingHandler objects can really only change the response being sent (e.g. intercept certain responses and change to the appropriate HTTP status).
The final HttpResponseMessage is given to the HttpServer instance.
which returns an Http response to the invoking client
Looking at the source code ,ODataController is another controller which is inherited from
ApiController with custom routing and formatting. So I guess all the logic applied for ApiController
applies to that as well.It also has Custom Formatting and Custom Routing applies using ODataFormatting and ODataRouting
What are the IIS pipelining steps ?
IIS pipelining steps are same like any other mvc controller .In essense,we have all the httpmodules and handlers which forms the pipeline.More details can be found asp.net application lifecycle. From this pieline,when an mvc request comes URLRoutingModule,MvcRouteHandler and Mvchandler works in tandem to serve an MVC request. Explained detailed for the next question.
How is the request handled when entering the ASP.NET controllers area ? When is routing applied ?
Everything starts with an ODataController .Almost everything in MVC is extensible(13 extensibility points in asp.net mvc) you name it and all those points are extended for OData. e.g Starting with Custom Controllers,we have
custom ODataActionSelector which is from IHttpActionSelector .You can find a sample implementation here
IActionValueBinder ,sample implementation here
IContentNegotiator
etc like this many more.
/// Defines a base class for OData controllers that support writing and reading data using the OData formats
/// </summary>
[ODataFormatting]
[ODataRouting]
[ApiExplorerSettings(IgnoreApi = true)]
public abstract class ODataController : ApiController
Receive first request for the application -> In the Global.asax file, Route objects are added to the RouteTable object.
Perform routing -> The UrlRoutingModule module uses the first matching Route object in the RouteTable collection .From ODataRouting, The routes are added to RouteTable collection.
Create MVC request handler -> The MvcRouteHandler object creates an instance of the MvcHandler class and passes the RequestContext instance to the handler
Create controller -> The MvcHandler object uses the RequestContext instance to identify the IControllerFactory object to create the controller instance with
Execute controller -> The MvcHandler instance calls the controller's Execute method
Invoke action -> For controllers that inherit from the ControllerBase class, the ControllerActionInvoker object that is associated with the controller determines which action method of the controller class to call, and then calls that method
7.Action returns all custom CreatedODataResult,UpdatedODataResult etc
There are Custom ODataMediaTypeFormatter registered for ODATA to format the data.

How to handle Incorrect JSON syntax in Spring MVC

I have a spring MVC Project, wherein I need to handle incorrect JSON syntax.
Spring MVC throws an error as text/html, which looks like:
Apache Tomcat/7.0.47 - Error report HTTP Status 400 - type Status reportmessage description The request sent by the client was syntactically incorrect.Apache Tomcat/7.0.47
However I want to throw my own exception in JSON format.
Is there any way to do it?
Thanks
I just ran into this as well, here's what I found to fix it:
The Spring MVC docs reference HttpMessageConverter as responsible for converting a #ResponseBody. For JSON, you're likely using a MappingJackson2HttpMessageConverter, which when attempting to convert a message can throw a HttpMessageNotReadableException.
If you have some form of exception handler for that, you can intercept the 400 response.
You can debug to see which Exception is actually thrown (might be a TypeMismatchException or something like that). Then, you can specify an error handler in your controller like
#ExceptionHandler(TypeMismatchException.class)
public String handleTypeMismatchException(TypeMismatchException ex) {
}
Now, in this controller method you can do whatever you want, like passing it the model, request, response etc. You can send to a view, redirect or in your case use a ResponseBody or however else you would like to serve your JSON error.

IllegalStateException:STREAM when calling response.getWriter

This is a method that's used for handle ajax request. So the output is written to the response
public ModelAndView myAction(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception
{
//call other methods and send the response as arg
//call getWriter on the response
}
According to this doc, I would definitely have an IllegalStateException if I call getWriter having already called getOutputStream(), so I suspect the methods I passed the response to did this although I don't really see them doing so...
The only thing for sure is that at some point, one of the methods may do response.sendError().
Does this some how call getOutputStream()?
HttpServletResponse#sendError() commits the response and send an error status code. The javadoc states
If the response has already been committed, this method throws an
IllegalStateException. After using this method, the response should be
considered to be committed and should not be written to.
In other words, after you call that method, the HTTP response has basically been sent. It makes no sense to call any of the getOutputStream() or getWriter() methods. Your Servlet container further makes it foolproof by throwing an Exception if you attempt to.
I had similar issues but I had not called sendError(), just setContentType() before that. As per this source, it can trigger the same behaviour:
I am guessing its because you have already opened the stream by
calling the resp.setContentType("text/plain"); method, and are then
trying to get a Writer object. You can either use Stream based
classes, or Writer based classes - not both.
Either remove the setContentType(), or send the response using
response.getOutputStream() method. That should solve the problem.
And indeed, it resolved the similar error for me.

Java Servlet request.getRequestURL() logged abnormal string

In one my servlet running in public domain, I got an abnormal string log from the request.getRequestURL() method. I keep logging the details and found an entry which is "http://answers.yahoo.com". Can some one help me in analyzing how this could have happened and also how to achieve it. Ideally the log should be the URL address in the browser using which a user or a device invokes the servlet.
For example if the registered name of the server mapped to the IP is http://www.alphabeta.com/x_serv?a=2, the logs should be alphabeta.com
What exactly do you want to log?
Use the method getServerName() from interface javax.servlet.ServletRequest if you only need a host name. It returns the host name of the server to which the request was sent.
Use in conjunction with getServerName() and the method getServletPath() if you want to get the URL without any parameters on which was caused by your servlet. The method getServletPath() from interface javax.servlet.http.HttpServletRequest returns the part of this request's URL that calls the servlet but does not include any extra path information or a query string.
And the following code fragment will determine your page's absolute URL:
String uri = request.getRequestURI();
if (request.getQueryString() != null) {
uri += '?' + request.getQueryString();
}
URL reconstructedUrl = new URL(request.getScheme(),
request.getServerName(),
request.getServerPort(),
uri);
logger.info("The full URL: " + reconstructedUrl.toString());
Where URL class is from the package java.net.

Resources