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 жестко закодирован. Поменяй при необходимости.

Другие вопросы по тегам