问题
For a project for my company, I have to send emails containing embedded URLs, which the user will be prompted to follow.
For example, a person registers on the website, and then the Struts2 application sends an email to that person in which there is a URL to confirm the subscription.
So far, the form submission, and sending the email (from inside the action), work just fine. The problem on which I'm stuck is that I can't find a way to generate the URL I'd like to embed in the mail body.
I must be doing it the wrong way, but I was thinking about something like what follows:
public String send() throws Exception {
StringBuffer body = new StringBuffer();
HashMap<String, String> params = new HashMap<String, String>();
params.put("id", "xxxxxyyyyyaaaaa");
body.append("Veuillez vous rendre ici :");
body.append(UrlManager.getUrlForAction("action", params));
SendMail sendMail = new SendMail();
sendMail.send("me@me.fr", "Information", body.toString());
return SUCCESS;
}
where there would be a UrlManager
(something that could be made available by the framework) with a method getUrlForAction()
that gets an action and its parameters as input and that outputs a String containing the corresponding URL (like http://mysite.mycompany.com/confirm?id=xxxxxyyyyyaaaaa
).
Does anyone have any ideas or pointers on how to do that?
EDIT:
I tried using UrlProvider
, but I get a null pointer exception on the determineActionUrl
call. Maybe I'm using it the wrong way.
HashMap<String,Object> params = new HashMap<String,Object>();
params.put("id", data.getMd5());
UrlProvider up = new ComponentUrlProvider(
new Component(ServletActionContext.getValueStack(ServletActionContext.getRequest())),
ServletActionContext.getRequest().getParameterMap());
downloadUrl = up.determineActionURL("confirm", "/", "GET",
ServletActionContext.getRequest(),
ServletActionContext.getResponse(),
params,
"http", true, true, true, true);
回答1:
You need to create the properties (dependencies) in your action
@Inject
public void setActionMapper(ActionMapper actionMapper) {
this.actionMapper = actionMapper;
}
private UrlHelper urlHelper;
@Inject
public void setUrlHelper(UrlHelper urlHelper) {
this.urlHelper = urlHelper;
}
then in the action you could write something like
Map<String, Object> parameters = new HashMap<>();
ActionMapping mapping = new ActionMapping("action", "namespace", "", parameters);
String uri = actionMapper.getUriFromActionMapping(mapping);
String url = urlHelper.buildUrl(uri, ServletActionContext.getRequest(), ServletActionContext.getResponse(), parameters, "http", true, false, true, false);
回答2:
You may take a look at Struts' UrlProvider.determineActionURL, which does what you need.
UPDATE Indeed I needed to use this method some weeks ago and I remember some NPE's rising around... At the end, I was able to write the following code (adapted from my app):
String getMyActionUrl() throws Exception {
ActionInvocation invocation = (ActionInvocation) ActionContext
.getContext().get(ActionContext.ACTION_INVOCATION);
org.apache.struts2.components.URL url = new org.apache.struts2.components.URL(invocation.getStack(), getServletRequest(),
getServletResponse());
url.addParameter("parameterToBeDeleted", null);
url.addParameter("newParam", newValue);
url.setActionMapper(new DefaultActionMapper());
url.setUrlHelper(new DefaultUrlHelper());
String myUrl = url
.getUrlProvider()
.determineActionURL(
"MyActionName",
invocation.getProxy().getNamespace(),
invocation.getProxy().getMethod(),
getServletRequest(),
getServletResponse(),
getServletRequest().getParameterMap(),
"http",
true, true, false, false);
return myUrl;
}
Notes:
MyActionName is here as a String -- not a great maintanable code. Make sure it matches the name you give to the action (which may differ from the name of the Action class handling calls to that action).
http is hardcoded. Change if needed.
来源:https://stackoverflow.com/questions/17449117/struts-2-sending-mail-with-embedded-url