Vae
Vae

Reputation: 60

Is there a way to access HttpRequest type inside a @Controller method

I have tried to find the answer to this, but I cannot seem to find what I am looking for. So I apologize if this question already exists.

PROBLEM:
I want to be able to access the request type of a request inside of a generic method within my Controller.

DESCRIPTION:
Using Spring ROO and Spring MVC, I have developed a small web service that will respond with certain tidbits from a database when queried. In one of my controller classes, I have some methods that handle some variety of GET, PUT, POST, etc., for the URIs that are mapped within the @RequestMapping parameter.

For example:

@RequestMapping(method = RequestMethod.Get, value = "/foo/bar")
@ResponseBody
public ResponseEntity<String> getFooBar() {
    // stuff
}

If a request is made to the web service that it is not currently mapped, a 405 error is returned (which is correct), but I want to return more information along with a 405 response. Maybe respond with something like:

"I know you tried to execute a [some method], but this path only handles [list of proper methods]."

So I wrote a short method that only has the RequestMapping:

@RequestMapping(value = "/foo/bar")

I have found that the method with this mapping will catch all unhandled request types. But I am having trouble accessing the information of the request, specifically the type, from within the method.

QUESTION:
A. How can I access the request type from within the method?
OR
B. Is this the right approach? What would be the right approach?

EDIT
ANSWER:

I added a HttpServletRequestobject to the method parameters. I was able to access the method type from that.

I tried using HttpRequest, but it didn't seem to like that much.

Thanks all!

Upvotes: 0

Views: 2003

Answers (3)

artbristol
artbristol

Reputation: 32407

You can add a method parameter of HttpServletRequest, but I think you'd be better off continuing to reply with 405. A client should then make an HTTP OPTIONS call (see How to handle HTTP OPTIONS with Spring MVC?) and you can return the list of allowed methods there.

Upvotes: 2

Steve
Steve

Reputation: 9480

In answer to "A", just add "HttpRequest req" as an additional argument to your controller methods. Spring will automatically inject a reference to the request, and you can play with headers to your heart's content.

In answer to "B" - "What would be the right approach", how about this?

In order to return that 405, Spring has raised a MethodArgumentNotValidException. You can provide custom handling for this like so:

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public MyMethodArgumentMessage handleMathodArgumentNotValidException(
        MethodArgumentNotValidException ex) {
    BindingResult result = ex.getBindingResult();
    MyMethodArgumentMessage myMessage = 
            new MyMethodArgumentMessage(result.getFieldErrors());
    return myMessage;
}

You should take a look at the @ExceptionHandler annotation. This lets you add methods such as the following to your controller. You can define your own exceptions and appropriate custom handlers for them. I use it to return well-structured XML and JSON from REST services. Although for it to work, you need to throw specific exceptions from your controller methods.

A good walk-through of using this was provided by Petri Kainulkainen in his blog: http://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-adding-validation-to-a-rest-api/

Upvotes: 0

Bassem Reda Zohdy
Bassem Reda Zohdy

Reputation: 12942

A. you can access request if you mentioned it as parameter in controller method

public ... getFooBar(HttpRequest request) {
...
}

B. you do not need to add any other description as the 405 status is descriptive.

Upvotes: 0

Related Questions