Pull to refresh

Сервлеты — маленький трюк с Reflection

Reading time2 min
Views2.8K

Задача:


Необходимо написать сервлет, который содержит кучу методов, имена которых совпадают с URL.
Например, у нас 3 URL адреса:

myhost/userservice/registration
myhost/userservice/login
myhost/userservice/anotherAction


которые обрабатывает сервлет UserServiceServlet, вот так:



public class UserServiceServlet extends HttpServlet {
    public void registration(HttpServletRequest request, HttpServletResponse response) {
         //....   
    }

    public void login(HttpServletRequest request, HttpServletResponse response)  {
         //....
    }

    public void anotherAction(HttpServletRequest request, HttpServletResponse response) {
         //....   
    }
}


Как же это сделать?



В первую очередь пишем базовый сервлет:


public class BaseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            String method = getMethod(req);  // получаем метод, например "login" или "trampampam";
            if (method != null && !"".equals(method)) {
                callMethod(method, req, resp); // вызываем метод
            }
        } catch (Exception e) {
            // log exception
            req.getRequestDispatcher(WebPages.PAGE_404).forward(req, resp);
        }
    }

    private String getMethod(HttpServletRequest request) {
        String method = request.getPathInfo();  // путь, например "/login"
        if (!"".equals(method)) {
            return method.substring(1, method.length()); // возвращаем подстроку без "/"
        }
        return null;
    }

    private void callMethod(String method, HttpServletRequest request, HttpServletResponse response) throws  Exception
           // вот так вот просто вызвать метод с помощью рефлекшн
            this.getClass().getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class).invoke(this, request, response);
    }
}


Дальше пишем свой сервлет:


public class UserServiceServlet extends BaseServlet {
    public void registration(HttpServletRequest request, HttpServletResponse response) {
         //....   
    }

    public void login(HttpServletRequest request, HttpServletResponse response)  {
         //....
    }

    public void anotherAction(HttpServletRequest request, HttpServletResponse response) {
         //....   
    }
}


а в web.xml:


<servlet>
    <servlet-name>User</servlet-name>
    <servlet-class>mypackage.UserServiceServlet</servlet-class>
    </servlet><servlet-mapping>
    <servlet-name>User</servlet-name>
    <url-pattern>/userservice/*</url-pattern>
</servlet-mapping>


Теперь можно создавать сколь угодно методов в вашем сервлете! Отделить логику, оказывается, достаточно просто! Удачи! ;-)
Tags:
Hubs:
Total votes 8: ↑7 and ↓1+6
Comments16

Articles