Map spring rest controller to a path without the servlet context - java

I have a spring boot application with the following context path:
server.servlet.context-path:/api
I need to write a rest controller that's mapped to
http://localhost:8080/logout
instead of http://localhost:8080/api/logout
Is there a way to achieve this? changing the "server.servelt.context-path" value is not an option.
this is what I tried and didn't work:
#GetMapping(value="../signout"){
public void logout(){
}

Nero, you say you can't change the "server.servlet.context-path" value. I bet you say this because you don't want to break the API, but I think you can manage to change this without breaking the API. Set the context-path to blank, which is permitted. Then in your application change the "api" mapping, which I assume is currently "/", to "api".
Change server.servlet.context-path:/api to server.servlet.context-path:/ or maybe server.servlet.context-path: (no slash). (Supposedly this is the default so you might just remove this entry altogether.)
Somewhere in your application change #RequestMapping("/") to #RequestMapping("/api").
Now you can also have #GetMapping(value="/signout") and you will have resources at http://localhost:8080/logout and http://localhost:8080/api.
I don't know what mapping annotations you happen to be using, but hopefully this is clear enough.

It may not be possible within that application to go outside its context root. Maybe you can create a separate Rest service app for that particular url and take it from there.

Related

Accessing a Filter object through a WebApplicationContext

I want to call a method on a Filter object after it has been added according to the web.xml definition. All I got is a WebApplicationContext object (let's call it: wac).
I'm able to add new Filter objects via: wac.getServletContext().addFilter("otherfilter", otherFilter);
Also, I can test successfully for its existence via: wac.getServletContext().getFilterRegistration("myfilter")
But how may I access (and possibly modify) Filter objects which have been added before?
I'm not sure how to do it exactly as you want, but this problem is usually solved using different approach.
You can declare your Filter as a bean in your application context and then register a DelegatingFilterProxy in web.xml to delegate filtering to your filter.
In this case your filter will be a regular Spring bean, and you'll be able to access it like any other bean.
The Servlet API does not provide any mechanism to directly access a Filter instance once it has been added to a ServletContext. The best you are going to get with the Servlet API is the FilterRegistration interface you have already found which lets you modify the same set of configuration options as you can via web.xml.
Depending on exactly what you want to do, you might be able to code your way around this problem using init parameters but that is never going to be a particularly clean solution. I'd go with the DelegatingFilterProxy solution suggested by axtavt.

Spring Requestmapping with condition based on server-side parameter

I have a controller (Spring Controller) that will serve json to a mobile app.
Various servers run our software. Not all will be configured to serve mobile requests.
I've added a bean of class Integer with the id of an object containing various system parameters necessary to handle requests.
This bean is defined in xml and autowired into the controller.
The autowiring uses (required = false) so we can run without a value defined in xml.
I have checked and found that the autowired Integer is indeed null if not defined in xml.
What I would like to do now is add to my requestmappings in a way that will match one method if that Integer is null and the regular method when the Integer is not null (basically, we'll reply with a standard json error object).
This seems like it'd be pretty straightforward with some sort of AOP, but I've little experience aside from using Spring. Most conditional info in the Requestmapping annotation seems to be based on request parameters, not server-side variables.
Any ideas?
I think that is better use a property-placeholder to load a properties file from the classpath. In this way you can deploy the same war file in different servers and use a different property file for each server (putting it in the AS classpath).
Once you did it you can use a variable in your controller (or in an interceptor if you want to leave the controller's code clean) and do something like this:
#Controller
public class MyController{
#Value("${mobile.enabled}")
private boolean mobileEnabled;
#RequestMapping("/mobile")
public Object json(){
if (!mobileEnabled)
throw new IllegalStateException("This server can't do it!");
}
//create the json
return result;
}
And a properties file like:
mobile.enabled=true
when you want to enable it, or false when don't.

How do I support localization with Jersey?

I am designing a REST API that I would like to be localizable in the future.
Therefore I am defining the URLs to be of the form
/en/<resource_url>
With the intention of being able to support
/fr/<resource_url>
In the future if need be.
However I only want to define each resource url service once. Therefore I figure I need to get the URL parsed and rewritten without the language piece of the URL before it is matched to services. Finally that language should be made available to the services somehow for them to localize if necessary.
How can I achieve this?
I am using Jersey 1.17 inside Jetty container embedded in a larger server process.
You can make the /en/ or the /fr/ part a variable. Then set your locale to the value of the variable. Here's an example:
#Path("/{locale}/username")
public class UserResource {
#GET
#Produces("text/xml")
public String getUser(#PathParam("locale") String locale) {
...
}
}
But that may not be the best way to go about it. After answering, I found this other SO question that is a better way to solve the problem: Getting the client locale in a jersey request With this way, you don't need to add this to the URL. Just make the client set a header.

Spring MVC Request mapping, can this be dynamic/configurable?

With Spring MVC, I know how you set the RequestMapping in every controller and method/action.
But what if I wanted this to be configurable, so for example I the following controllers:
BlogController
- with methods for listing blogs entries, single entry, new, update, etc.
ArticleController
- with methods for listing articles entries, single entry, new, update, etc.
Now in my application, the administrator can setup 2 blogs for the webiste, and 1 article section so the urls would be like:
www.example.com/article_section1/ - uses ArticleController
www.example.com/blog1/ - uses BlogController
www.example.com/blog2/ - uses BlogController
Maybe after a while the administrator wants another article section, so they just configure that with a new section like:
www.example.com/article_section2/
This has to work dynamically/on-the-fly without having to restart the application of course.
My question is only concerned with how I will handle url mappings to my controllers.
How would this be possible with Spring MVC?
I only know how to map urls to controllers using #RequestMapping("/helloWorld") at the controller or method level, but this makes the url mappings fixed and not configurable like how I want it.
Update:
I will be storing the paths in the database, and with the mapping to the type of controller so like:
path controller
/article_section1/ article
/blog1/ blog
/blog2/ blog
..
With the above information, how could I dispatch the request to the correct controller?
Again, not looking to reload/redeploy, and I realize this will require more work but its in the spec :)
Would this sort of URL mapping work for you?
www.example.com/blog/1/
www.example.com/blog/2/
If yes, then that's easy: Spring 3 supports path variables: http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html#mvc-ann-requestmapping-advanced
Alternatively, you can create a generic request mapping and your own sub-dispatcher that reads a config file, but I think that's probably more work than it's worth.
Truly changing the request mappings at runtime might be hard (and not really recommended, since small errors can easily occur). If you still wish to do it, perhaps JRebel, and more specificly LiveRebel can be interesting for live redeployment of code and configuration.
Otherwise, like other posts suggested, RequestMappings supports wildcards, the limits of this should be clear after a quick read of the official documentation.
Try using with #RequestMapping wild cards as below:
#RequestMapping(value="/article_section*/"}
public void getArticle(....){
//TODO implementation
}
#RequestMapping(value="/blog*/"}
public void getBlog(....){
//TODO implementation
}
Hope this helps!!!
Also another solution might be to create a custom annotation that holds the already defined path on the #RequestMapping and also the new one to apply, let's say #ApiRestController.
Then, before the Spring context loads, the #Controller classes can be changed to have their annotation values changed at runtime by the new one (with the desired path). By doing this, Spring will load the enhanced request mapping and not the default one.
Created a small project to exemplify this for someone that needs this in the future https://gitlab.com/jdiasamaro/spring-api-rest-controllers.
Hope it helps.
Cheers.
doesn't this work?
#RequestMapping("/helloWorld*")

A servlet or filter that dynamically maps /xxx/yyy/zzz to class XxxYyyZzz.java

I want to write a servlet or filter that automatically maps the url /xxx/yyy/zzz to class XxxYyyZzz.java.
For example the following URLs will map to the following java classes:
/comment/add --> CommentAdd.java
/comment/delete --> CommentDelete.java
/comment/view --> CommentView.java
/search --> Search.java
/viewposts --> Viewposts.java
In addition the servlet or filter must comply with two extra requirements:
The servlet or filter should have a servlet mapping of "/*", I dont want a prefix with several servlets "/comment/*", "/search", etc.
Maybe difficult, but having a servlet mapping of /* should not allow it to override the JSP processing. Meaning, if a class is not found, it should check if a jsp page exists and run it.
I want to know how can this be done using the Servlet API. Please don't refer me to any framework that does the job. Just show me the code.
The classes that are mapped to will follow the command pattern or could be a subclass of the HttpServlet. In both cases, a method should exist like "execute(HttpServletRequest request, and HttpServletResponse response)". This method will be automatically executed once the URL is accessed and the java class is figured out possibly using a single servlet or filter.
I'm not sure, if I got what you mean. In case I did:
You need nothing special, write a single Servlet mapped to "/", so it gets everything. Parse the PATH_INFO (don't know now how it gets called in Java), use Class.forName (or use a pre-filled Map), and call its method execute.
Here is a http://www.tuckey.org/urlrewrite/ filter implementation that might help you. Check it out. I have not used it myself though.
You can use Stripes framework with its default NameBasedActionResolver config.

Categories

Resources