I'm being asked to take over a piece of code. Being that I am not an seasoned Spring developer, I have a question on what is the URI when both the controller and method does not specify a value for #RequestMapping.
For example, the code looks like this:
#Controller
public class FooController {
#RequestMapping
public String getThis(String input) {
return "This";
}
}
So what is the URL that I need to access the getThis method?
Sometime back i also had the same doubt. Am thinking that Controller without #RequestMapping will throw an exception (am not sure).
For method case:
If you don't have any values in #RequestMapping, method will listen on Controller path and you dint specify any method so it will listen ALL HTTP Methods.
Your method will not be reachable and you can see this via a warning message from Spring like :
21:57:50.608 [main] DEBUG o.s.w.s.h.BeanNameUrlHandlerMapping -
Rejected bean name
'org.springframework.context.annotation.internalConfigurationAnnotationProcessor':
no URL paths identified
If you need to have this method in the root URL, you need to use the value "/" instead of nothing.
Related
I am trying to call REST API method (method been declared without #Path annotation).
Resource path for this API has been loaded in server start up itself using BaseRestServer.rootPath.
I expect that this API will get called by default, as there are no other apis available to process the request.
But when i call this api, I am getting '404 Not Found' as response.
code is something like, as given below,
**#Path("")**
public class JobResource{
#POST
#Consumes("application/job")
#Produces("application/job")
public Response postJob(
#Context HttpServletRequest hRequest, Job job){
}
}
resource path has been defined in the server file itself, as given below
BaseRestServer.rootPath = "/shared/job/"+companyName.
Reason on why i have not used resource path in the class is, that it allows only constant value inside #Path annotation.
But in my case, companyName value changes dynamically
When I pass this dynamic value inside #Path("/shared/job/"+companyName), i am getting compilation error as 'The Value for annotation attribute Path.value must be a constant expression'
I have a file on a server available via Https I want to access using Spring's Resource abstraction. I want Spring to resolve the resource and inject it into the constructor of my Bean like this:
public class MyClass {
public MyClass(
#Value("https://myserver.com/myfile") Resource resource) {
// do something using the resource
}
}
The issue is that I cannot figure out how to include the username and password for basic authentication into this pattern. I tried the "common" style
#Value("https://username:password#myserver.com/myfile")
but it looks like this is not understood correctly. The server is responding with HTTP status 401 - Unauthorized. I copied the string and perfomed the same query using wget and it worked. So there is no issue with my credentials but most likely with the syntax used to define the resource.
Is there a valid syntax for this in Spring or must I fetch the config in an alternative way setting the Authentication header by hand?
This feels wrong, and I'd prefer it if you didn't do it this way...but you can rely on #Value to inject the property value. Note the use of #Autowired here.
#Component
public class MyClass {
private String resourceUrl;
#Autowired
public MyClass(#Value(${external.resource.url}) String resourceUrl) {
this.resourceUrl = resourceUrl;
}
// The rest of your code
}
Then you could place into the property external.resource.url whichever value you liked...including your full URL with username and password.
I want to call attention that this is probably not a desirable thing to do, since you want to be able to inject the URL, username and password as separate things into your application. This gives you an idea of how you can accomplish it with one component, and while I strongly encourage you to split this up instead (and whatever you do, do not check the properties file in with those values into your source control), I leave the mechanical part of splitting this into more values as an exercise for the reader.
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!
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.
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.
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/
I am working on a WebService using JAX-RS/Jersey.
I've set up a ContainerRequestFilter whose purpose is to authenticate the user. I only need to protect some of the paths with authentication, the rest can be available to everyone.
I want to retrieve matchedResources / matchedResults via ExtendedUriInfo in my ContainerRequestFilter so that I can check if the path should be protected or not. Is there a way to create a filter which is invoked after ExtendedUriInfo is populated, but before the matched resource class and method is invoked?
Here is a more general answer (for instance if you're using another jax-rs implementation like CXF):
Just add the following in your filter class as an instance variable:
#Context
ResourceInfo info;
"javax.ws.rs.container.ResourceInfo is a new JAX-RS context which can
be injected into filters and interceptors and checked which resource
class and method are about to be invoked."
(source : https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Basics#JAX-RSBasics-ResourceInfo)
Original answer here
Found a way to do it with ContainerRequestFilter:
public void filter(ContainerRequestContext requestContext) {
UriRoutingContext routingContext = (UriRoutingContext) requestContext.getUriInfo();
ResourceMethodInvoker invoker = (ResourceMethodInvoker) routingContext.getInflector();
Class<?> className = invoker.getResourceClass();
Method methodName = invoker.getResourceMethod();
}
I managed to figure it out.
The approach I have found to work is to abandon doing this in the ContainerRequestFilter and create a ResourceFilterFactory instead. In the ResourceFilterFactory I can use
AbstractMethod.isAnnotationPresent(clazz)
to determine if my custom annotation is present. If my annotation is present, I can then return a list containing my AuthenticationContainerRequestFilter.
Another tip for anyone reading this answer is that injection in the ContainerRequestFilter will not work when using the ResourceFilterFactory approach. What I did was to do any injection in the ResourceFilterFactory and then pass the injected objects to the ContainerRequestFilter via its constructor.
What does this warning mean in Jersey 1.4:
WARNING: A sub-resource method, public final java.lang.String com.XXX.render(),
with URI template, "/", is treated as a resource method
This is how the method looks:
#GET
#Produces(MediaType.APPLICATION_XML)
#Path("/")
public final String render() {
return "test";
}
Why do you need specify such path for method? #Get is enough to tell jersey that it is default method for entire class (I'm assuming that your class has some #Path("/MyRes") annotation).
Looks like you had the same problem last week with How to route JAX-RS request conditionally, depending on the suffix? - any luck fixing it there?
A look around on the net reveals you may have set-up your constructor incorrectly - have a read through http://jersey.576304.n2.nabble.com/Problem-using-the-JerseyTest-class-td3256608.html - someone who had a similar problem and was able to resolve it.