Struts 2 - отправка почты со встроенным URL
Для проекта для моей компании я должен отправить электронные письма, содержащие встроенные URL-адреса, за которыми пользователю будет предложено следовать.
Например, человек регистрируется на веб-сайте, а затем приложение Struts2 отправляет электронное письмо этому человеку, в котором есть URL-адрес для подтверждения подписки.
Пока что отправка формы и отправка электронного письма (изнутри действия) работают просто отлично. Проблема, с которой я застрял, заключается в том, что я не могу найти способ сгенерировать URL, который я хотел бы вставить в текст письма.
Должно быть, я делаю это неправильно, но я думал о чем-то вроде следующего:
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;
}
где будет UrlManager
(что-то, что может быть сделано доступным фреймворком) с помощью метода getUrlForAction()
который получает действие и его параметры в качестве входных данных и выводит строку, содержащую соответствующий URL (например, http://mysite.mycompany.com/confirm?id=xxxxxyyyyyaaaaa
).
У кого-нибудь есть идеи или указания о том, как это сделать?
РЕДАКТИРОВАТЬ:
Я пытался с помощью UrlProvider
, но я получаю исключение нулевого указателя на determineActionUrl
вызов. Может быть, я использую это неправильно.
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);
2 ответа
Вам нужно создать свойства (зависимости) в вашем действии
@Inject
public void setActionMapper(ActionMapper actionMapper) {
this.actionMapper = actionMapper;
}
private UrlHelper urlHelper;
@Inject
public void setUrlHelper(UrlHelper urlHelper) {
this.urlHelper = urlHelper;
}
тогда в действии вы могли бы написать что-то вроде
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);
Вы можете взглянуть на UrlProvider.determineActionURL от Struts, который делает то, что вам нужно.
ОБНОВЛЕНИЕ Действительно, мне нужно было использовать этот метод несколько недель назад, и я помню, что некоторые NPE поднимались вокруг... В конце я смог написать следующий код (адаптированный из моего приложения):
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;
}
Заметки:
MyActionName здесь как String - не очень хороший обслуживаемый код. Убедитесь, что оно совпадает с именем, которое вы даете действию (которое может отличаться от имени класса Action, обрабатывающего вызовы этого действия).
http жестко закодирован. Поменяй при необходимости.