Запуск J1C

Для того что бы соблюсти требование однократного запуска J1C мы установим экземпляр класса j1c.ru.V7 "глобальным"в web-приложении, а точнее как атрибут контекста сервлета.
Что бы иметь возможность запускать и останавливать J1C реализуем "стартер". Этот стартер будет давать возможность задавать каталог базы 1С и создавать j1c.ru.V7 как атрибут контекста. Кроме того, этот же сервлет показывает статус работы J1C, если J1C уже запущен.
Начальная страничка для запуска сервлета создается следующим сервлетом.

import j1c.ru.V7;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;



public class ControlJ1C extends HttpServlet{
	
	private void printLauncheForm (HttpServletRequest req, HttpServletResponse resp) throws IOException{
		PrintWriter out = resp.getWriter();
		
		String catalogBase="<КАТАЛОГ БАЗЫ>";
		
		out.println("<form method=\"post\" action=\""+req.getContextPath()+"/launch\">");
		out.println("<table>");
		
		out.println("<caption>Параметры запуска</caption>");			  
		out.println("<tr><td>Каталог:</td><td><input type=\"text\" name=\"catalogBase\" value=\""+catalogBase+"\" size=\"100\"></td></tr>");
		out.println("<tr><td><input type=\"submit\" value=\"Запустить\"></td></tr>");
		out.println("</table>");
		
		out.println("</form>");
	}
	
	private void printStateForm (HttpServletRequest req, HttpServletResponse resp) throws IOException{
		PrintWriter out = resp.getWriter();
		
		V7 v7 = (V7)getServletContext().getAttribute("ru.j1c.V7");
		
		out.println("<form method=\"post\" action=\""+req.getContextPath()+"/stop\">");
		out.println("<table>");
		
		out.println("<caption>Параметры запуска</caption>");
		out.println("<tr><td>Каталог:</td><td>"+v7.getCatalogDataBase().getAbsoluteFile()+"</td></tr>");
		out.println("<tr><td><input type=\"submit\" value=\"Остановить\"></td></tr>");
		out.println("</table>");
		out.println("</form>");
	}

	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.setContentType("text/html; charset=\"UTF-8\"");
		PrintWriter out = resp.getWriter();
		
		ServletContext context = getServletContext();
		
		V7 v7 = (V7)context.getAttribute("ru.j1c.V7");
		
		out.println("<html><head>");
		out.println("<title>Управление запуском J1C</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h2>Управление запуском J1C</h2>");
		
		//context.log("action = "+action+";catalogBase="+req.getParameter("catalogBase")+";v7="+v7);
		
		if(v7==null){//значит приложение не запущено
			printLauncheForm(req, resp);
		}
		else {//приложение запущено - покажем статус
			printStateForm(req, resp);
		}
		
		out.println("</body></html>");
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		doGet(req, resp);
	}
}

После того как мы задали каталог базы идет переадресация на сервлет, который собственно запускает J1C.
Объект создается и подключается к базе с учетной записью самой 1С. При этом j1c.ru.V7 устанавливается как атрибут контекста.

import j1c.ru.V7;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Launch extends HttpServlet{
	
	private void forwardError(Exception e, HttpServletRequest req, HttpServletResponse resp) 
			throws ServletException, IOException{
		
		req.setAttribute("error", e);
		RequestDispatcher dispatcher = req.getRequestDispatcher("/error");
		dispatcher.forward(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		
		req.setCharacterEncoding("UTF-8");
		
		String catalogBase = req.getParameter("catalogBase");
		if(catalogBase==null){
			forwardError(new Exception("Каталог базы не задан"), req, resp);
			return;
		}
		
		V7 v7 = (V7)getServletContext().getAttribute("ru.j1c.V7");
		
		if(v7!=null){
			forwardError(new Exception("J1C уже запущен"), req, resp);
			return;
		}
				
		try {
			v7 = new V7();
			synchronized (v7) {
				v7.connect(catalogBase);
				getServletContext().setAttribute("ru.j1c.V7", v7);
			}
			RequestDispatcher dispatcher = req.getRequestDispatcher("/control");
			dispatcher.forward(req, resp);
		} catch (Exception e) {
			forwardError(e, req, resp);
		}
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		doPost(req, resp);
	}

}

Собственно на этом почти все, что нужно для того что бы J1C был запущен и был готов отрабатывать запросы клиентов. Нам осталось только привести еще 2 вспомогательных сервлета. Один отвечает за остановку J1C, а другой выводит ошибки клиенту, если вдруг они возникнут.
Остановка J1C:

import j1c.ru.V7;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class Stop extends HttpServlet{
	
	private void forwardError(Exception e, HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException{
			req.setAttribute("error", e);
			RequestDispatcher dispatcher = req.getRequestDispatcher("/error");
			dispatcher.forward(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		
		ServletContext context = getServletContext();
		V7 v7 = (V7)context.getAttribute("ru.j1c.V7");
		if(v7!=null){
			try {
				synchronized (v7) {
					v7.close();
					context.setAttribute("ru.j1c.V7", null);
				}
				
				RequestDispatcher dispatcher = req.getRequestDispatcher("/control");
				dispatcher.forward(req, resp);
			} catch (Exception e) {
				forwardError(e, req, resp);
			}
		}
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		doPost(req, resp);
	}
}

Вывод ошибок:

import j1c.ru.V7;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class Error extends HttpServlet{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		
		resp.setContentType("text/html; charset=\"UTF-8\"");
		PrintWriter out = resp.getWriter();
		
		Exception e = (Exception)req.getAttribute("error");
		
		out.println("<html><head>");
		out.println("<title>Управление запуском J1C</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h2>Ошибка работы</h2>");
		out.println("<p>"+e.getMessage()+"</p>");
		
		out.println("</body></html>");
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		doPost(req, resp);
	}
}

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