I'm trying to build a way for my application to have a URL pattern/scheme like that of applications like Twitter. For example myapplication.com/username where the username is an actual username treated as a parameter. This parameter will be used to display the user related page. My application also has this URL scheme where the username is a prefix for other resources e.g. myapplication.com/username/accountsettings or myapplication.com/username/profile. The username acts some sort of sub-context path.
As the title suggests, I'm using Stripes for it. What I'm doing now is create a custom ActionResolver where I take out the first non-empty string from the URL binding (the username in this case) since my ActionBeans do not take into account the username prepended to the URL. So for example, the action bean that handles myapplication.com/username/accountsettings is only bound to /accountsettings.
When I tried to use the custom ActionResolver as ActionResolver.Class init param for the Stripes filter, it doesn't seem to be working. It seems like it's still using the default ActionResolver. How do I alter this?
Also, is there an easier/more intuitive way to do this? I'm not very familiar with Stripes and URL bindings so is there a facility in Stripes that would allow me to do this without extending/altering the framework components?
Thanks.
I agree with lucas, URL mappings should be done by UrlBinding annotation. There is no need to start messing around with URL remapping filters, that will only break the Stripes system in generating correct URL’s for you.
This is how it should look like:
#UrlBinding("{username}/profile/")
public class MyProfileAction implements ActionBean {
private ActionBeanContext context;
private String username;
public ActionBeanContext getContext() {
return context;
}
public void setContext(ActionBeanContext context) {
this.context = context;
}
public void setUsername(String username) {
this.name = name;
}
public String getUsername() {
return username;
}
#DefaultHandler
public Resolution view() {
return new ForwardResolution(“/WEB-INF/MyProfile.jsp”);
}
}
I stumbled upon URL Rewrite Filter and it seems to fit the needs of my application so far.
Stripes does have this built in. It's called the #URLBinding annotation, and it was included in Stripes 1.5. There is some documentation here, and there was more in the Stripes book IIRC.
#UrlBinding("/foo/{bar}/{baz}") maps
the action to "/foo" and indicates
that the "bar" and "baz" parameters
may be embedded in the URL. In this
case, the URL /foo/abc/123 would
invoke the action with bar set to
"abc" and baz set to "123".
Related
I have done a few MVC controllers now and used the spring form tags to pass data back and forth but I realise now my actual understanding is a little thin. In my current case I could actually just send the response as url parameters but there are about 15 and I would prefer to send it as a pojo if possible.
My actual question... is ... is it possible to set up a spring style model attribute in a jsp without the attribute having been passed in and without using the form tags ?
So for example something along the lines of
//Pojo
Class personclass
{
private String name + getters and setters
private String address + getters and setters
private String phone + getters and setters
...
}
////first mvc call
#RequestMapping ("/")
Public ModelAndView LandingPage()
{
// no mention of Person pbject
Return mandvobject;
}
//jsp page
//This is the question!
SET ModelAttribute that wasn't passed in to the page
personclass = X
//New MVC call without a submit
window.open ("/NewMVCCall")
//New mvc call
#RequestMapping ("/NewMVCCall")
Public void newMVCPage(#ModelAttribute ("pc") personclass pc, Model model)
{
//process pc object
}
Or am I missing the point and I would have to send it as a json string parameter? Sorry my grasp of this is pretty rudimentary and I'm not sure whether I could quite easily set my own http form content or whether it is because I have used Spring form objects so far that I haven't grasped the complexity of what is going on behind the scenes (i.e form tags converting pojos to json and so on) ?
Many thanks if anyone has the time to set me on the right path...
I am not sure if I am understood your question correctly but you can link a Model to your controller without having to manually pass it to a the view every time you need it, spring will take care of that:
in your Controller :
public class MyController{
#ModelAttribute("pc")
public PersonneClass getPersonnelClass(){
return new PersonneClass();
}
#RequestMapping ("/NewMVCCall")
Public void newMVCPage(#ModelAttribute ("pc") personclass pc, Model model)
{
//process pc object
}
//other methods
}
It is a good practice to stick to java conventions when naming classes so
(personneClass ) must start with an uppercase (PersonneClass) .
I want to create a restful link for each user, who registered on my page. For Example: User "testuser" registered on my page and his profile should be accessible through www.mypage.com/users/testuser.
How can i realize something in wicket?
in WebApplication implementation add to init():
mountPage("/users/${id}", UserPage.class);
and in UserPage.class :
public UserPage(PageParameters parameters) {
String id = parameters.get("id").toString();
...
}
Is it possible to introduce a additional url path element? Something like "http://server/users/userid/testuser"? If you have mount your page to the url "users" then the page will be initialized by wicket using the constructor with the PageParameters parameter:
public class UserPage extends WebPage {
public UserPage(PageParameters pars) {
String userId = pars.getParameterValue("userid");
...
}
}
Have a look at mounting pages in wicket 1.5. It describes the methods to 'mount', aka make available, a page on a certain url. Parameters to that page (in your case, the user name) can either be via name or via index (position).
You will be interested in the positioning parameters.
I know this question has been asked quite a few times, however, I have a different approach of what I want to achieve.
Since Play 1.1, you're able to match hosts. This is very useful, however, it means that for every controller, I will need to pass through the subdomain route param. This is quite a burden and repeatful if I have hundreds of controllers which use the subdomain param.
Is there not a way to create a filter which looks at the host name before everything else is executed and then sets an on-the-fly config value for that request?
For example (brainstorming), a filter would do the following:
// use request host, but hard-coded for now...
String host = "test.example.com";
Pattern p = Pattern.compile("^([a-z0-9]+)\\.example\\.com$");
Matcher m = p.matcher(host);
if (m.matches()) {
// OUT: test
System.out.println(m.group(1));
System.setProperty("host", m.group(1));
}
And in the models I'd do something like System.getProperty("host");
I know this isn't how it should be done, but I'm just brainstorming.
At least with this way:
I don't have to pass the subdomain param through to every
controller.
I don't have to pass the subdomain param through to any models
either
Models have direct access to the subdomain value so I can filter out objects that belong to the client
Also, I'm aware that System.setProperty() always applies to the entire JVM; which is a problem. I only want this value to be available throughout the duration of the request. What should I use?
Let's analyse. How would you do it? What would be a good approach? Is this possible with Play? I'm sure there are quite a few running into this problem. Your input is highly appreciated.
I think you are close. If I had to do this, I would write a controller annotated with #Before and have that method extract the hostname from the request headers and put it in renderArgs.
Something like this (I haven't tested it):
public class HostExtractor extends Controller {
#Before
public static void extractHost() {
// Code to read from request headers and extract whatever you need here.
String host = 'Your Code Here'
renderArgs.put("hostname", host);
}
}
Then, in your other controllers, you tell it you want to use that controller above as a filter.
#With(HostExtractor.class)
public class MyController extends Controller {
public static void homepage() {
String hostname = renderArgs.get("host", String.class);
// Do whatever logic you need to render the page here.
}
}
Again, I haven't tested this, but I'm doing something similar to cache objects in memcache. I hope that helps!
In my Play app when I use reverse routing to generate links, forward slashes in parameters are being escaped, and I'd rather they weren't.
For example:
Contact Us
generates a working link, but takes you to /about%2Fcontact.html rather than /about/contact.html. (Entering /about/contact.html in the address bar also goes to the right place.)
I'm doing this because I've only got a few pages that do anything interesting and the rest are basically static -- they only use the basic template features (extends,include,get,set). Since creating separate controllers and actions for each of them would be overkill I've set up a single action to handle all of them.
public class Application extends Controller {
public static void page(String path) {
render("/static/" + path + ".html");
}
}
handled with one route:
GET /{<.+>path}.html Application.page
Any idea how I can change things around so that the slashes aren't encoded?
Since we (apparently) can't override the way RouteArgs works, we can decode the given url in the method, like this :
public class Application extends Controller {
public static void page(String path) {
render("/static/" + URLDecoder.decode(path, "UTF-8"); + ".html");
}
}
But be aware of security risks! (well, .html not so much, but just in case ...)
I'm working on converting a legacy project to Spring (trying to adjust little as possible for now) and I'm running into a small issue with mapping/translating legacy parameters to a model attribute object. I may be completely wrong in thinking about this problem but it appears to me that to translate a parameter to a specific model attribute setter is to pass in the request parameter through a method for creating a model attribute and manually call the correct setter:
#ModelAttribute("form")
public MyForm createMyForm(#RequestParameter("legacy-param") legacy) {
MyForm myForm = new MyForm();
myForm.setNewParam(legacy);
return myForm;
}
I don't necessarily want to change the request parameter name yet since some javascript and JSPs are depending on it being named that way but is there any way to do something like this? Or is there a different way to map/translate request parameters to model attributes?
public class MyForm {
#ParameterName("legacy-param")
private String newParam;
public void setNewParam(String value) { ... }
public String getNewParam() { ... }
}
#Controller
public class MyController {
#RequestMapping("/a/url")
public String myMethod(#ModelAttribute("form") MyForm myForm, BindingResult result) { ... }
}
The way you've written that model attribute method is indeed odd. I'm not entirely clear what you're actually trying to do.Assuming there are many parameters, you're going to end up with an awful lot of instances of MyForm in your ModelMap. A more 'normal' way to create model attribute would be like this:
#ModelAttribute("legacyParamNotCamel")
public MyForm createMyForm(#RequestParameter("legacy-param-not-camel") String legacy) {
return legacy;
}
Then in the JSP you can refer to it directly in expression language. e.g.,
<c:out value="${legacyParamNotCamel}"/>
If you want to put them onto a form backing object, you need to do it all in a single method that creates the object, not make new copies of it in each method. (assuming your form has more than a single parameter associated with it.)
--
It seems like what you're really trying to do though is translate the parameter names in the request before the web data binder gets ahold of it, so that you can bind oddly named parameters onto a java bean? For that you'll need to use an interceptor that translates the names before the binding process begins, or make your own subclass of the databinder than can take a property name translation map.
You placed the #ModelAttribute at the Method Level but the intention seems to be more of a formBackingObject hence we should be dealing at the Method Parameter Level
There's a difference.
I put up an explanation here on my blog along examples at Spring 3 MVC: Using #ModelAttribute in Your JSPs at http://krams915.blogspot.com/2010/12/spring-3-mvc-using-modelattribute-in.html