2015-05-22 1 views
1

Мы строим webapp, который общается с удаленным API. Я хотел бы создать клиент для удаленного API, как это:В Spring-MVC, как мне динамически задавать аргументы конструктора атрибута сеанса?

def RemoteApi 
    constructor (username, password) 
    getCurrentUser() //implementation will use username and password 
    getEmployees() //implementation will use username and password 
    ... 

Суть в том, я хочу передать в учетные данные для этого клиента в процессе строительства, и есть все остальные методы используют эти учетные данные. Моим вторым требованием я хочу, чтобы этот экземпляр RemoteApi находился в сеансе.

Я узнал, как передать динамические аргументы конструктора here.

Я узнал, как создать атрибут сеанса here.

Но я не могу найти способ объединить эти две техники. Из того, что я собираю, вам нужно создать экземпляр атрибута сеанса в собственном методе, подобном методу getter. Этот метод getter-like не будет иметь доступа к полям формы, поэтому я не смогу передать учетные данные на этом этапе.

Вот где я застрял:

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.SessionAttributes; 

import java.util.Map; 

@Controller 
@SessionAttributes("remoteClient") 
public class LoginController { 

    @Value("${company.name}") 
    private String companyName; 

    @Autowired 
    private RemoteClient remoteClient; 

    @ModelAttribute("remoteClient") 
    public RemoteClient addRemoteClientToSession() { 
     return remoteClient; //how do initialize this with credentials in here? 
    } 

    @RequestMapping("/") 
    public String showLogin(Model model) { 
     model.addAttribute("credentials", new Credentials()); 
     return "login"; 
    } 

    @RequestMapping("/login") 
    public String login(@ModelAttribute("credentials") Credentials credentials, Map<String, Object> model) { 
     if (remoteClient.auth(companyName, credentials.getUsername(), credentials.getPassword())) { 
      model.put("fullname", remoteClient.findCurrentUser().getName()); 
      return "projectView"; 
     } else { 
      return "login"; 
     } 
    } 
} 

Update: Возможно решение связано с this technique. Раньше я не знал о ModelAndView.

+0

Если у вас есть работающее решение для этого, пожалуйста, напишите ответ :) –

+0

@LuiggiMendoza я не уверен, если я еще. Если это сработает, я обновлю –

ответ

0

В статье, связанной с этим вопросом, была необходимая техника. Что бы я сделал, создайте @AutowiredRemoteApiFactory, который имеет метод newInstance(Credentials) и передает его в addObject. Реализация newInstance, вероятно, закончится использованием ключевого слова new. Если кто-то знает, как избежать этой детали, я бы хотел это услышать.

Вот его пример оптимальный для моих потребностей:

@Controller 
@SessionAttributes("remoteApi") 
public class SingleFieldController { 

    @Autowired 
    private RemoteApiFactory remoteApiFactory;  

    @RequestMapping(value="/single-field") 
    public ModelAndView singleFieldPage() { 
     return new ModelAndView("single-field-page"); 
    } 

    @RequestMapping(value="/remember") 
    public ModelAndView rememberThought(@MethodAttribute("credentials") Credentials credentials) { 
     ModelAndView modelAndView = new ModelAndView(); 
     modelAndView.addObject("remoteApi", remoteApiFactory.newInstance(credentials)); 
     modelAndView.setViewName("single-field-page"); 
     return modelAndView; 
    } 
} 
Смежные вопросы