Унификация разработки

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
про загрузку файлов...
увы, но DAS не является многопоточным (где-то была инфа, но я проверил на практике) в случае отправки аттача (другие не проверял)
выход есть - создание сервлета...
создавать с "0" - это достаточно неудобный способ, есть проще - xPage, хотя он добавит объекты JSF, но если все-равно используем xPages - так и поступим ;)
XML:
 <xe:restService id="JSONService" pathInfo="JSONService"
      rendered="false" preventDojoStore="true" disableTheme="true">
      <xe:this.service>
          <xe:customRestService serviceBean="com.setralubs.JsonService"
              contentType="application/json">
          </xe:customRestService>
      </xe:this.service>
на хэпагу ставим такой код, где com.setralubs.JsonService класс который будет в Code->Java (в дизайнере)
для размещения аттача я задействовал ODA (было влом возиться с голыми объектами домины)
Java:
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;

import org.openntf.domino.Database;
import org.openntf.domino.Document;
import org.openntf.domino.Session;
import org.openntf.domino.View;
import org.openntf.domino.ViewEntry;
import org.openntf.domino.ViewEntryCollection;
import org.openntf.domino.utils.Factory;
public class JsonService extends CustomServiceBean {

    @Override
    public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
        // TODO Auto-generated method stub
        super.renderService(service, engine);
        HttpServletRequest request = engine.getHttpRequest();
        HttpServletResponse response = engine.getHttpResponse();
        response.setHeader("Content-Type", "application/json; charset=UTF-8");
        try {
            PrintWriter writer = response.getWriter();
            JsonJavaObject jo = new JsonJavaObject();
            String id=request.getParameter("id");
            long cnt=0;
            //System.out.println("id length: "+id.length());
            if (id!=null && !id.isEmpty() &&id.length()==32){
                Session ses = Factory.getSession();
                Database db=ses.getCurrentDatabase();
                Document doc=db.getDocumentByUNID(id);
                if (doc!=null){
                    doc.removeItem("Body");
                    //doc.computeWithForm(false, false);
                    System.out.println("content type: "+request.getContentType());
                    jo.put("Content-type",request.getContentType());
                    if(request.getContentType().contains("application/vnd.")
                            || request.getContentType().contains("application/octet-stream")){
                        System.out.println("Processing...");
                        RichTextOutputStream rtos;
                        rtos = new RichTextOutputStream(doc);
                        String batch=doc.getItemValueString("batch");
                        String prodName=doc.getItemValueString("prodName");
                        rtos.setFileName(prodName.replaceAll("[^a-zA-Z0-9.-]", "_")
                                +"("+batch+")"+".docx");
                        byte[] buffer = new byte[8 * 1024];
                        int bytesRead;
                        InputStream bodyIs=request.getInputStream();
                        while ((bytesRead = bodyIs.read(buffer)) != -1) {
                            rtos.write(buffer, 0, bytesRead);
                            cnt+=bytesRead;
                        }
                        bodyIs.close();
                        rtos.close();
                        rtos.save();
                    }else if(request.getContentType().contains("application/json")){
                        String sBody=extractPostRequestBody(request);
                        jo.put("body",sBody);
                        cnt=sBody.getBytes("UTF-8").length;
                    }
                }
            }else{
                System.out.println("TEXT body");
                String sBody=extractPostRequestBody(request);
                jo.put("body",sBody);
                cnt=sBody.getBytes("UTF-8").length;
            }
            jo.put("argument", id);
            jo.put("body size", cnt);
            writer.write(jo.toString());
            writer.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  
    private static String extractPostRequestBody(HttpServletRequest request) {
        Scanner s = null;
//System.out.println("Getting body string..");
        try {
            s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s.hasNext() ? s.next() : "";
    }
}
важный момент, для использования класса (адаптированного мной) RichTextOutputStream - удаление поля РТ иначе майм не создать
для сравнения - время загрузки файла через сервлет менее секунды (1,4Мбайта), через DAS - 7секунд
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
текстовая "заглушка" сделана для теста сервиса через (или curl, кому как удобнее)
класс для РТ
Java:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

//source from http://www.nsftools.com/tips/RichTextOutputStream.java
import org.openntf.domino.Database;
import org.openntf.domino.Document;
//import org.openntf.domino.impl.MIMEEntity;
//import org.openntf.domino.impl.MIMEHeader;
import org.openntf.domino.MIMEEntity;
import org.openntf.domino.RichTextItem;
import org.openntf.domino.Session;
import org.openntf.domino.Stream;
import org.openntf.domino.utils.Factory;

import lotus.domino.NotesException;

public class RichTextOutputStream extends OutputStream {
    private final String classID="::"
            + new Throwable().getStackTrace()[0].getClassName() + "::";

    //private static final int MAX_BUF = 524288;//2048;
    private static final int MAX_BUF = 2048;
    private Session ses =null;
    private Stream stream =null;
    //private Database db=null;
    private org.openntf.domino.MIMEEntity body =null;
    private String fileName="defname";
    private byte[] buffer=new byte[MAX_BUF];
    private int count;
    private Database db;
    private Document logDoc;
    private RichTextItem logBody;
    private Access access = new Access();

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    String getFileName() {
        return fileName;
    }


    public RichTextOutputStream(String fname){
        init(fname);
    }
    void init(String fname){
        init(fname, null);
    }
    
    public RichTextOutputStream(Document doc){
        init(null, doc);
    }
    
    void init(String fname, Document doc){
        ses = Factory.getSession();// SessionType.CURRENT
        stream=ses.createStream();
        ses.setConvertMIME(false);
        db = ses.getCurrentDatabase();
        if (fname!=null)this.fileName=fname;
        if (doc==null){
            logDoc = db.createDocument();
            logDoc.replaceItemValue("Form", Access.LOG_FRM);
            //logBody = logDoc.createRichTextItem(Access.BODY_FLD);
            access.setDefAccess(logDoc, ses.getEffectiveUserName());
        }else logDoc=doc;
        
        body=logDoc.createMIMEEntity(Access.BODY_FLD);
    }

/*    public RichTextOutputStream(Session ses, String name, Document doc) {
        this.ses=ses;
        stream=ses.createStream();
        ses.setConvertMIME(false);
        body=doc.createMIMEEntity(name);
    }
*/   
    public Document getDoc(){
        return body.getParent();
    }

    /**
     * Closes the RichTextOutputStream, so that no more data can be written to it.
     */
    public void close () throws IOException {
        flush();
        super.close();
    }

    /**
     * Overrides the default flush() method in the OutputStream class, although this
     * method really does nothing, because we're not buffering data and we're always
     * writing directly to the underlying RichTextItem.
     * @throws IOException
     */
    public void flush() throws IOException {
        // since we're always writing directly to the RichTextField,
        // this doesn't really do anything
        // System.out.println("Flusing...");
        if (count > 0) {
            flush2Stream(buffer);
        }
        if (stream != null && stream.getBytes() > 0) {
            //System.out.format("RT Flushing: %s ...\n", getFileName());
            final org.openntf.domino.MIMEEntity child = body.createChildEntity();
            org.openntf.domino.MIMEHeader header = child.createHeader("Content-Disposition");
            header.setHeaderVal("attachment; filename=\"" + getFileName() + "\"");
            String fileSuffix = getFileName().substring(getFileName().lastIndexOf(".") + 1);
            child.setContentFromBytes(stream, MIMEType.get(fileSuffix), MIMEEntity.ENC_IDENTITY_BINARY);
            stream.close();
        }
    }
  
/**
     * Saves the RichTextItem we're working on by saving the Document that
     * contains it.
     */
    public boolean save () throws IOException {
        // a convenience method to save the Document we're working on
        // (we could have done this with the flush() method, but that could
        // cause unexpected results if this OutputStream is wrapped in
        // another Stream or Writer that auto-flushes)

        return body.getParent().save();
    }

    /**
     * Writes an array of bytes to the RichTextItem (converting it first to a String).
     *
     * @param  b        an array of bytes
     */
    public void write (byte[] b) throws IOException {
        if (//rtitem==null &&
                body!=null) {
            super.write(b);
        }else {
            write(new String(b));
        }
    }

    /**
     * Writes len bytes from a byte array to the RichTextItem, starting at offset off
     * (converting it first to a String).
     *
     * @param  b        an array of bytes
     * @param  off      the start offset in the data
     * @param  len      the number of bytes to write
     */
    public void write (byte[] b, int off, int len) throws IOException {
        if (//rtitem==null &&
                body!=null) {
            super.write(b, off, len);
        }else {
//            write(new String(b, off, len));
        }
    }

    /**
     * Writes a single byte to the RichTextItem (converting it first to a String).
     *
     * @param  b        a single byte
     * @throws NotesException
     */
    public void write (byte b) throws IOException {
        if (//rtitem==null &&
                body!=null) {
            if (count<MAX_BUF) {
                buffer[count]=b;count++;
            }else {
                flush2Stream(buffer);
                buffer[0]=b;count=1;
            }
            //stream.write(buffer);
        }else {
//            write(String.valueOf((char)b));
        }
    }

    private void flush2Stream(byte[] bytesIn) {
        // TODO Auto-generated method stub
        //optimization for memory operation
        if (stream==null)return;
        if (count+1<MAX_BUF) {
            //copy when buffer isn't full
            byte[] buff=Arrays.copyOf(bytesIn, count);
            stream.write(buff);
        }
        else {
            stream.write(bytesIn);
        }
        count=0;
        //Arrays.fill( bytesIn, (byte)0 );
    }

    /**
     * Writes a String to the RichTextItem.
     *
     * @param  str      a String to write
     */
    public void write(String str) throws IOException {
        // make sure we have a RichTextItem to write to
/*       
        if (rtitem == null)
            throw new IOException(
                    "The RichTextItem that you are trying to write to is null (maybe close() was called)");

        // and make sure we have a String to write
        if (str == null)
            return;

        // if we're not converting linefeeds, all we have to do is write
        // the String; otherwise, we'll need to tokenize it and replace
        // \r and \n with addNewLine calls (making sure to call it only
        // once for Windows \r\n linefeed combinations)
        if (!convertLF) {
            rtitem.appendText(str);
        } else {
            boolean wroteCR = false;
            String token = "";
            StringTokenizer st = new StringTokenizer(str, "\r\n", true);

            while (st.hasMoreTokens()) {
                token = st.nextToken();
                if (token.equals("\r")) {
                    rtitem.addNewLine(1);
                    wroteCR = true;
                } else if (token.equals("\n")) {
                    if (!wroteCR)
                        rtitem.addNewLine(1);
                    wroteCR = false;
                } else {
                    rtitem.appendText(token);
                    wroteCR = false;
                }
            }
        }
*/   
    }

    /**
     * Writes an entire InputStream to the RichTextItem (converting its contents to a String).
     *
     * @param  in       an InputStream
     * @throws NotesException
     */
    public void write (InputStream in) throws IOException {
        int howManyBytes;
        byte[] bytesIn = new byte[2048];
        while ((howManyBytes = in.read(bytesIn)) >= 0) {
            stream.write(bytesIn);
            Arrays.fill( bytesIn, (byte)0 );
        }
        flush();

/*        while ((howManyBytes = in.read(bytesIn)) >= 0)
            write(bytesIn, 0, howManyBytes);
*/
    }

    @Override
    public void write(int b) throws IOException {
        write((byte) b);
    }
}
 

garrick

Lotus Team
26.10.2009
1 356
149
BIT
353
Я смотрю org.openntf.domino себе на сервер поставили. Её же как расширение ставить надо, я прав?
На сколько стабильно оно работает?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
а чем стандартный не устраивает?
как сессию получать в сервлете?
NotesFactory не заработает, передать "снаружи" - если и можно, то с бубнами
проверил, что заработает так:lotus.domino.Session session = ExtLibUtil.getCurrentSession();
в обоих случаях: session.getUserName() будет сервер ses.getEffectiveUserName() авторизованный юзер
НО во втором варианте - куча ресайклов по всякому поводу
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
Я смотрю org.openntf.domino себе на сервер поставили. Её же как расширение ставить надо, я прав?
На сколько стабильно оно работает?
да, через updateSite, нестабильности не заметил, юзаю еще и OpenLog - удобно (большинство исключений туда падает)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
сделал реверсивный map , для маймов, но (разумеется) ограничен (т.к. есть повторения в прямом соответствии)
например exe, bin, lha имеют "application/octet-stream"
Java:
import java.util.HashMap;
import java.util.Map;
//http://w3schools.sinsixx.com/media/media_mimeref.asp.htm
public class MIMEType {
    private static final Map<String, String> revMap=new HashMap<String, String>();
    private static final Map<String, String> map=createMap();
    private static final String defType = "application/octet-stream";

    public static String get(String key) {
        if (map.containsKey(key))return map.get(key);
        return defType;
    }

    private static Map<String, String> createMap() {
        // TODO Auto-generated method stub
        Map<String,String> map=new HashMap<String,String>();
//    map.put(" ","application/octet-stream");
        map.put("323","text/h323");
        map.put("acx","application/internet-property-stream");
        map.put("ai","application/postscript");
        map.put("aif","audio/x-aiff");
        map.put("aifc","audio/x-aiff");
        map.put("aiff","audio/x-aiff");
        map.put("asf","video/x-ms-asf");
        map.put("asr","video/x-ms-asf");
        map.put("asx","video/x-ms-asf");
        map.put("au","audio/basic");
        map.put("avi","video/x-msvideo");
        map.put("axs","application/olescript");
        map.put("bas","text/plain");
        map.put("bcpio","application/x-bcpio");
        map.put("bin","application/octet-stream");
        map.put("bmp","image/bmp");
        map.put("c","text/plain");
        map.put("cat","application/vnd.ms-pkiseccat");
        map.put("cdf","application/x-cdf");
        map.put("cer","application/x-x509-ca-cert");
        //map.put("class","application/octet-stream");
        map.put("clp","application/x-msclip");
        map.put("cmx","image/x-cmx");
        map.put("cod","image/cis-cod");
        map.put("cpio","application/x-cpio");
        map.put("crd","application/x-mscardfile");
        map.put("crl","application/pkix-crl");
        map.put("crt","application/x-x509-ca-cert");
        map.put("csh","application/x-csh");
        map.put("css","text/css");
        map.put("dcr","application/x-director");
        map.put("der","application/x-x509-ca-cert");
        map.put("dir","application/x-director");
        map.put("dll","application/x-msdownload");
        //map.put("dms","application/octet-stream");
        map.put("doc","application/msword");
        map.put("dot","application/msword");
        map.put("dvi","application/x-dvi");
        map.put("dxr","application/x-director");
        map.put("eps","application/postscript");
        map.put("etx","text/x-setext");
        map.put("evy","application/envoy");
        //map.put("exe","application/octet-stream");
        map.put("fif","application/fractals");
        map.put("flr","x-world/x-vrml");
        map.put("gif","image/gif");
        map.put("gtar","application/x-gtar");
        map.put("gz","application/x-gzip");
        map.put("h","text/plain");
        map.put("hdf","application/x-hdf");
        map.put("hlp","application/winhlp");
        map.put("hqx","application/mac-binhex40");
        map.put("hta","application/hta");
        map.put("htc","text/x-component");
        map.put("htm","text/html");
        map.put("html","text/html");
        map.put("htt","text/webviewhtml");
        map.put("ico","image/x-icon");
        map.put("ief","image/ief");
        map.put("iii","application/x-iphone");
        map.put("ins","application/x-internet-signup");
        map.put("isp","application/x-internet-signup");
        map.put("jfif","image/pipeg");
        map.put("jpe","image/jpeg");
        map.put("jpeg","image/jpeg");
        map.put("jpg","image/jpeg");
        map.put("js","application/x-javascript");
        map.put("latex","application/x-latex");
        //map.put("lha","application/octet-stream");
        map.put("lsf","video/x-la-asf");
        map.put("lsx","video/x-la-asf");
        //map.put("lzh","application/octet-stream");
        map.put("m13","application/x-msmediaview");
        map.put("m14","application/x-msmediaview");
        map.put("m3u","audio/x-mpegurl");
        map.put("man","application/x-troff-man");
        map.put("mdb","application/x-msaccess");
        map.put("me","application/x-troff-me");
        map.put("mht","message/rfc822");
        map.put("mhtml","message/rfc822");
        map.put("mid","audio/mid");
        map.put("mny","application/x-msmoney");
        map.put("mov","video/quicktime");
        map.put("movie","video/x-sgi-movie");
        map.put("mp2","video/mpeg");
        map.put("mp3","audio/mpeg");
        map.put("mpa","video/mpeg");
        map.put("mpe","video/mpeg");
        map.put("mpeg","video/mpeg");
        map.put("mpg","video/mpeg");
        map.put("mpp","application/vnd.ms-project");
        map.put("mpv2","video/mpeg");
        map.put("ms","application/x-troff-ms");
        map.put("mvb","application/x-msmediaview");
        map.put("nws","message/rfc822");
        map.put("oda","application/oda");
        map.put("p10","application/pkcs10");
        map.put("p12","application/x-pkcs12");
        map.put("p7b","application/x-pkcs7-certificates");
        map.put("p7c","application/x-pkcs7-mime");
        map.put("p7m","application/x-pkcs7-mime");
        map.put("p7r","application/x-pkcs7-certreqresp");
        map.put("p7s","application/x-pkcs7-signature");
        map.put("pbm","image/x-portable-bitmap");
        map.put("pdf","application/pdf");
        map.put("pfx","application/x-pkcs12");
        map.put("pgm","image/x-portable-graymap");
        map.put("pko","application/ynd.ms-pkipko");
        map.put("pma","application/x-perfmon");
        map.put("pmc","application/x-perfmon");
        map.put("pml","application/x-perfmon");
        map.put("pmr","application/x-perfmon");
        map.put("pmw","application/x-perfmon");
        map.put("pnm","image/x-portable-anymap");
        map.put("pot,","application/vnd.ms-powerpoint");
        map.put("ppm","image/x-portable-pixmap");
        map.put("pps","application/vnd.ms-powerpoint");
        map.put("ppt","application/vnd.ms-powerpoint");
        map.put("prf","application/pics-rules");
        map.put("ps","application/postscript");
        map.put("pub","application/x-mspublisher");
        map.put("qt","video/quicktime");
        map.put("ra","audio/x-pn-realaudio");
        map.put("ram","audio/x-pn-realaudio");
        map.put("ras","image/x-cmu-raster");
        map.put("rgb","image/x-rgb");
        map.put("rmi","audio/mid");
        map.put("roff","application/x-troff");
        map.put("rtf","application/rtf");
        map.put("rtx","text/richtext");
        map.put("scd","application/x-msschedule");
        map.put("sct","text/scriptlet");
        map.put("setpay","application/set-payment-initiation");
        map.put("setreg","application/set-registration-initiation");
        map.put("sh","application/x-sh");
        map.put("shar","application/x-shar");
        map.put("sit","application/x-stuffit");
        map.put("snd","audio/basic");
        map.put("spc","application/x-pkcs7-certificates");
        map.put("spl","application/futuresplash");
        map.put("src","application/x-wais-source");
        map.put("sst","application/vnd.ms-pkicertstore");
        map.put("stl","application/vnd.ms-pkistl");
        map.put("stm","text/html");
        map.put("svg","image/svg+xml");
        map.put("sv4cpio","application/x-sv4cpio");
        map.put("sv4crc","application/x-sv4crc");
        map.put("swf","application/x-shockwave-flash");
        map.put("t","application/x-troff");
        map.put("tar","application/x-tar");
        map.put("tcl","application/x-tcl");
        map.put("tex","application/x-tex");
        map.put("texi","application/x-texinfo");
        map.put("texinfo","application/x-texinfo");
        map.put("tgz","application/x-compressed");
        map.put("tif","image/tiff");
        map.put("tiff","image/tiff");
        map.put("tr","application/x-troff");
        map.put("trm","application/x-msterminal");
        map.put("tsv","text/tab-separated-values");
        map.put("txt","text/plain");
        map.put("uls","text/iuls");
        map.put("ustar","application/x-ustar");
        map.put("vcf","text/x-vcard");
        map.put("vrml","x-world/x-vrml");
        map.put("wav","audio/x-wav");
        map.put("wcm","application/vnd.ms-works");
        map.put("wdb","application/vnd.ms-works");
        map.put("wks","application/vnd.ms-works");
        map.put("wmf","application/x-msmetafile");
        map.put("wps","application/vnd.ms-works");
        map.put("wri","application/x-mswrite");
        map.put("wrl","x-world/x-vrml");
        map.put("wrz","x-world/x-vrml");
        map.put("xaf","x-world/x-vrml");
        map.put("xbm","image/x-xbitmap");
        map.put("xla","application/vnd.ms-excel");
        map.put("xlc","application/vnd.ms-excel");
        map.put("xlm","application/vnd.ms-excel");
        map.put("xls","application/vnd.ms-excel");
        map.put("xlt","application/vnd.ms-excel");
        map.put("xlw","application/vnd.ms-excel");
        map.put("xof","x-world/x-vrml");
        map.put("xpm","image/x-xpixmap");
        map.put("xwd","image/x-xwindowdump");
        map.put("z","application/x-compress");
        map.put("zip","application/zip");
        map.put("docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        map.put("xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        map.put("xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template");
        map.put("xlsm","application/vnd.ms-excel.sheet.macroEnabled.12");
        map.put("xltm","application/vnd.ms-excel.template.macroEnabled.12");
        map.put("xlam","application/vnd.ms-excel.addin.macroEnabled.12");
        map.put("xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12");
        map.put("pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation");
        map.put("potx","application/vnd.openxmlformats-officedocument.presentationml.template");
        map.put("ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow");
        map.put("ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12");
        map.put("pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12");
        map.put("potm","application/vnd.ms-powerpoint.template.macroEnabled.12");
        map.put("ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12");
        for(Map.Entry<String, String>e:map.entrySet()){
            revMap.put(e.getValue(),e.getKey());
        }
        map.put(".xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        map.put(".xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template");
        map.put(".xlsm","application/vnd.ms-excel.sheet.macroEnabled.12");
        map.put(".xltm","application/vnd.ms-excel.template.macroEnabled.12");
        map.put(".xlam","application/vnd.ms-excel.addin.macroEnabled.12");
        map.put(".xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12");
        map.put(".pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation");
        map.put(".potx","application/vnd.openxmlformats-officedocument.presentationml.template");
        map.put(".ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow");
        map.put(".ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12");
        map.put(".pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12");
        map.put(".potm","application/vnd.ms-powerpoint.template.macroEnabled.12");
        map.put(".ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12");
        map.put(".docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        map.put(".pdf","application/pdf");

        return map;
    }
    public static String getKey(String value){
        return revMap.get(value);
    }

}
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
использую я в коде так
Java:
package com.setralubs;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;

import javax.faces.context.FacesContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openntf.domino.Database;
import org.openntf.domino.Document;
import org.openntf.domino.Session;
import org.openntf.domino.utils.Factory;

import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;
import com.ibm.xsp.extlib.util.ExtLibUtil;

import lotus.domino.NotesFactory;
import lotus.domino.NotesThread;
public class JsonService extends CustomServiceBean {

    @Override
    public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
        // TODO Auto-generated method stub
        super.renderService(service, engine);
        HttpServletRequest request = engine.getHttpRequest();
        HttpServletResponse response = engine.getHttpResponse();
        response.setHeader("Content-Type", "application/json; charset=UTF-8");
        //https://frostillic.us/f.nsf/posts/building-xpages-servlets-with-facescontext-access
        //ServletOutputStream out = response.getOutputStream();
        //FacesContext facesContext = this.getFacesContext(request, response);
        try {
            PrintWriter writer = response.getWriter();
            JsonJavaObject jo = new JsonJavaObject();
            String id=request.getParameter("id");
            long cnt=0;
            //System.out.println("id length: "+id.length());
            if (id!=null && !id.isEmpty() &&id.length()==32){
                Session ses = Factory.getSession();
                jo.put("sessionUser",ses.getEffectiveUserName());
                System.out.println("Session user: "+ses.getEffectiveUserName());
                Database db=ses.getCurrentDatabase();
                Document doc=db.getDocumentByUNID(id);
                if (doc!=null){
                    doc.removeItem("Body");
                    //doc.computeWithForm(false, false);
                    System.out.println("content type: "+request.getContentType());
                    jo.put("Content-type",request.getContentType());
                    if(request.getContentType().contains("application/vnd.")
                            || request.getContentType().contains("application/octet-stream")
                            || request.getContentType().contains("application/pdf")
                            ){
                        String ext=MIMEType.getKey(request.getContentType());
                        //System.out.println("Processing...");
                        RichTextOutputStream rtos;
                        rtos = new RichTextOutputStream(doc);
                        String batch=doc.getItemValueString("batch");
                        String prodName=doc.getItemValueString("prodName");
                        rtos.setFileName(prodName.replaceAll("[^a-zA-Z0-9.-]", "_")
                                +"("+batch+")"+"."+ext);
                        byte[] buffer = new byte[8 * 1024];
                        int bytesRead;
                        InputStream bodyIs=request.getInputStream();
                        while ((bytesRead = bodyIs.read(buffer)) != -1) {
                            rtos.write(buffer, 0, bytesRead);
                            cnt+=bytesRead;
                        }
                        bodyIs.close();
                        rtos.close();
                        rtos.save();
                    }else if(request.getContentType().contains("application/json")){
                        String sBody=extractPostRequestBody(request);
                        jo.put("body",sBody);
                        cnt=sBody.getBytes("UTF-8").length;
                    }
                }
            }else{
                System.out.println("TEXT body");
                String sBody=extractPostRequestBody(request);
                jo.put("body",sBody);
                cnt=sBody.getBytes("UTF-8").length;
            }
            jo.put("argument", id);
            jo.put("body size", cnt);
            //jo.put("user",this.getUserNameFromRequest(request));
            writer.write(jo.toString());
            writer.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    private static String extractPostRequestBody(HttpServletRequest request) {
        Scanner s = null;
//System.out.println("Getting body string..");
        try {
            s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s.hasNext() ? s.next() : "";
    }
    
    private String getUserNameFromRequest(HttpServletRequest request){
        String user = null;
        try{
              String LtpaToken = null;

              // Extract cookie named "LtpaToken"
              Cookie[] cookies = request.getCookies();
              if (cookies == null) {
                  return null;
              }

              for (Cookie cookie:cookies) {
                  System.out.println("name="
                          + cookie.getName());

                  if (cookie.getName().equals("LtpaToken")) {
                      LtpaToken = cookie.getValue();
                      System.out.println("got LTPA value:" + LtpaToken);
                      break;
                  }
              }
              if(LtpaToken!=null){
                    //NotesThread.sinitThread();
                    //lotus.domino.Session session = NotesFactory.createSession(request.getServerName(), LtpaToken);
                    System.out.println("Server: "+request.getServerName());
                    //lotus.domino.Session session = NotesFactory.createSession(request.getServerName(), request);
                    lotus.domino.Session session = ExtLibUtil.getCurrentSession();
                    user = session.getUserName();
//                    user = session.getUserNameObject().getAbbreviated();
                    session.recycle();
                    //NotesThread.stermThread();
              }
              System.out.println("Activity rest service: get user name:"+user);
        }catch(Exception e){
            e.printStackTrace();
        }
        return user;
    }
}
String ext=MIMEType.getKey(request.getContentType());
...
rtos.setFileName(prodName.replaceAll("[^a-zA-Z0-9.-]", "_") +"("+batch+")"+"."+ext);
для моих задач достаточно
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
не вижу смысла для отдельного топика...
Известный момент - порой надо "отдать" локальные файлы, по http, доминой эта задача решается, но со скоростью будут вопросы ;)
есть библиотеки на nio и на них уже есть готовый простенький сервачёк puzpuzpuz/http-nio-server
по коду посмотрел, с моего уровня java (не высокого) - вполне норм (смотрел несколько др. проектов - не понравилось и надо было допиливать)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
после этого ;) следует код для взаимодействия с OnlyOffice, я переписал с JS + у ОО документ сервера изменился формат возвращаемых данных (был XML стал JSON)
Java:
import com.ibm.commons.util.io.json.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import static com.setralubs.OptionsFromDB.*;

public class OnlyOfficeUtils {
    final org.slf4j.Logger LOG = LoggerFactory.getLogger(new Throwable().getStackTrace()[0].getClassName());
    final static String CONVERTSERVICE="ConvertService.ashx"; //OnlyOffice conversion service address
    final static JWT jwt=new JWT();
    final static OptionsFromDB opts=new OptionsFromDB(); //fetch all rows from options view
    static String secretJWT;

    static {
        try {
            secretJWT = opts.getFieldString(OPT_SECRETS,FLD_SECRETJWT); //field from option document
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    static String urlOO;
    static {
        try {
            urlOO = opts.getFieldString(OPT_SECRETS,FLD_DOCSERVER); //field from option document
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    File convert(String fName) throws IOException {
        String url = null;
        Properties preferences = new Properties();
        try {
            FileInputStream configFile = new FileInputStream("http4files.settings.properties");
            preferences.load(configFile);
            String port= String.valueOf(preferences.get("port"));
            String host= InetAddress.getLocalHost().getHostName();
            url="http://"+host+":"+port+"/"+fName;//address for local http server, see ru.puzpuzpuz.http Http4Files.java
        }catch(IOException e){
            LOG.error("trace:\n",e);
        }
        String outputType="pdf";
        JsonObject toPDF = new JsonJavaObject();
        toPDF.putJsonProperty("async",false);
        toPDF.putJsonProperty("filetype", FilenameUtils.getExtension(fName));
        toPDF.putJsonProperty("key",fName);
        toPDF.putJsonProperty("outputtype",outputType);
        toPDF.putJsonProperty("title",fName);
        toPDF.putJsonProperty("url",url);
        JsonObject payload = new JsonJavaObject();
        payload.putJsonProperty("payload",toPDF);
        String key = secretJWT();
        String jwtSigned=jwt.sign(payload.toString(), key);
        HttpUtils httpUtils=new HttpUtils();
        Map<String, String> props=new HashMap<>();
        props.put("Authorization", "Bearer "+jwtSigned); //OnlyOffice authorization
        HttpURLConnection conn=
                httpUtils.doPostStringWProperties(getUrlOO()+CONVERTSERVICE
                        ,null
                        , toPDF.toString(), props);
        if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){
            String ret=httpUtils.result2String(conn);
            String fileUrl= String.valueOf(getIgnoreCase(ret,"fileurl"));
            if (fileUrl!=null){
                LOG.debug("DocServer url for result: "+fileUrl);
                HttpURLConnection result=httpUtils.doGetStringWOauth(fileUrl,null);
                if (result!=null) {
                    File tmp = File.createTempFile("conv_", "."+outputType);
                    FileUtils.copyInputStreamToFile(httpUtils.result2Stream(result), tmp);
                    return tmp;
                }else{
                    LOG.error("File fetch error from: "+fileUrl);
                }
            }

/*
            //old variant for result (XML)
            Pattern pattern = Pattern.compile("(?i)<fileurl>(.+?)</fileurl>", Pattern.DOTALL);
            Matcher matcher = pattern.matcher(ret);
            if (matcher.find())
            {
                LOG.debug(matcher.group(1));
            }
*/

        }else {
            LOG.error("error code: " + conn.getResponseCode()
                    + "\nwith message: " + conn.getResponseMessage());
        }
        return null;
    }

    static String getUrlOO() {
        return urlOO;
    }

    static String secretJWT() {
        return secretJWT;
    }
    public Object getIgnoreCase(String jsonString, String key) {
        Map<String, Object> jsonMap=null;
        try {
             jsonMap = (Map<String, Object>)JsonParser.fromJson(JsonJavaFactory.instanceEx, jsonString);
        } catch (JsonException e) {
            LOG.error("trace:\n",e);
            return null;
        }
        for(Map.Entry<String,Object>e:jsonMap.entrySet()){
            if (e.getKey().equalsIgnoreCase(key)) return e.getValue();
        }
        return null;

    }
    public static void main(String[]args) throws IOException {
        OnlyOfficeUtils obj=new OnlyOfficeUtils();
        obj.convert("out1188689498385490682.docx");
    }
}
в мульти-поточном использовании столкнулся с недоступностью ОО на запрос - 504 ошибка, но это было при очень быстрых запросах на конвертации, в кол-ве 50 в секунду, можно делать ожидание и повтор, но я поленился, просто уменьшил кол-во потоков приложения до 10 со 100 (ExecutorService executor = Executors.newFixedThreadPool(10);)
 
Последнее редактирование:
  • Нравится
Реакции: alexas1

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
к-нить смотрел?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
отправка почты, через DAS
момент раз - у меня в АК не оказалось
27414

Mail - я тупо добавил в дизигнере
27415

надо учитывать присутствие мейл базы на текущем сервере (у авторизованного пользователя), либо задавать сервер из полученных данных (я так не делал)
JSON:
    "mailboxes": [
        {
            "owner": {
                "displayName": "admin",
                "distinguishedName": "admin/CRUINTERNET",
                "homeServer": "mail1/CRUINTERNET",
                "email": ""
            },
Java:
    int sendNotification(String subject, String body, String mailto) throws IOException {
        String methodName="->"+Thread.currentThread().getStackTrace()[1].getMethodName()+"()";
        int retCode=-1;
        String errText=null;
        HashMap<String,String> mailDbURIs=getMailDb();
        if (mailDbURIs != null) {
            String url = HttpUtils.BaseURI + httpUtils.dominoServer + mailDbURIs.get("outbox");
            if (httpUtils.isAuthorized()) {
                String mime = "MIME-Version: 1.0" +
                        "\nTo: " + mailto +
                        "\nSubject: " + subject +
                        "\nContent-Type: text/plain; charset=UTF-8\n\n" +
                        body;
                Map<String, String> props = new HashMap<>();
                props.put("Content-Type", "message/rfc822");
                HttpURLConnection conn = httpUtils.doPostStringWProperties(
                        url
                        , null
                        , mime
                        , props);
                retCode = conn.getResponseCode();
                if (retCode != HttpURLConnection.HTTP_CREATED) {
                    errText = conn.getResponseCode()
                            + "\nwith message: "
                            + conn.getResponseMessage();
                    LOG.error("error code: " + errText);
                }
                retCode = conn.getResponseCode();
            } else {
                errText = "Connection is not authorized for: " + url;
                LOG.error(errText);
            }
            if (errText != null) errors.put(methodName, errText);
        }
        return retCode;
    }

    HashMap<String,String> getMailDb() throws IOException {
        String methodName="->"+Thread.currentThread().getStackTrace()[1].getMethodName()+"()";
        HashMap<String,String> retMap=null;
        String errText=null;
        String url= HttpUtils.BaseURI + httpUtils.dominoServer + API_MAIL_URI;
        if (httpUtils.isAuthorized()) {
            int retCode=-1;
            HttpURLConnection conn = httpUtils.doGetString(url,null);
            retCode = conn.getResponseCode();
            if (retCode != HttpURLConnection.HTTP_OK) {
                errText = conn.getResponseCode()
                        + "\nwith message: "
                        + conn.getResponseMessage();
                LOG.error("error code: " + errText);
            } else {
                String ret = httpUtils.result2String(conn);
                //LOG.debug("server response: " + ret);
                ObjectMapper mapper = new ObjectMapper();
                JsonNode root = mapper.readTree(ret);
                JsonNode links = root.findValue("links");
                if(links!=null) {
                    retMap=new HashMap<String,String>();
                    Iterator<JsonNode> iterator = links.getElements();
                    Pattern pattern = Pattern.compile("http.+//.+?\\..+?(/.+" + API_MAIL_URI + "/.*)");
                    while (iterator.hasNext()) {
                        JsonNode link = iterator.next();
                        String href=link.findValue("href").asText();
                        if (href.startsWith("http")) {
                            Matcher matcher = pattern.matcher(href);
                            retMap.put(link.findValue("rel").asText(), (matcher.matches() ? matcher.group(1) : null));
                        }else
                            retMap.put(link.findValue("rel").asText(), href);
                    }
                }
            }
        }
        if (errText!=null)errors.put(methodName,errText);
        return retMap;
    }
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
сервис для получения списка на основе файла excel...
сделал привязанным к своим задачам, но исправить по смыслу несложно
Java:
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.logging.Level;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openntf.domino.xsp.XspOpenLogUtil;

import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;
public class BatchCheckService extends CustomServiceBean {
    private final String classID="::"
            + new Throwable().getStackTrace()[0].getClassName() + "::";

    @Override
    public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
        try {
            Throwable throwable = new Throwable();
            super.renderService(service, engine);
            HttpServletRequest request = engine.getHttpRequest();
            HttpServletResponse response = engine.getHttpResponse();
            PrintWriter writer = response.getWriter();
            //JsonJavaObject jo = new JsonJavaObject();
            boolean exists=request.getParameter("exists")!=null;
            //System.out.println("id length: "+id.length());
            BatchChecker obj=new BatchChecker();
            response.setHeader("Content-Type", "application/json; charset=UTF-8");
            writer.write("{\"body\": \"");
            if(request.getContentType()!=null && request.getContentType().contains(
                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                    )
                  ){
                //String ext=MIMEType.getKey(request.getContentType());
                InputStream bodyIs=request.getInputStream();

                XspOpenLogUtil.logEvent(throwable, this.classID
                        + throwable.getStackTrace()[1].getMethodName()+"(): "
                        +"Content-Type: "+request.getContentType(), Level.INFO,
                        null);
                
                response.setHeader("Content-Type", "application/json; charset=UTF-8");
                if (exists){
                    XspOpenLogUtil.logEvent(throwable, this.classID
                            + throwable.getStackTrace()[1].getMethodName()+"(): "
                            +"list for batches are existing", Level.INFO,
                            null);
                }else{
                    XspOpenLogUtil.logEvent(throwable, this.classID
                            + throwable.getStackTrace()[1].getMethodName()+"(): "
                            +"list for batches are absent", Level.INFO,
                            null);
                    //obj.testCheckingOut(writer);
                }
                obj.checking(bodyIs, writer, exists);
            }else //if(request.getContentType().contains("application/json"))
            {
                obj.testCheckingOut(writer);
            }
            writer.write("\"}");
            writer.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            XspOpenLogUtil.logError(e);
        }
    }
    
}
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
сама обработка
Java:
import com.ibm.xsp.webapp.XspHttpServletResponse;
import com.poiji.annotation.ExcelCellName;
import com.poiji.bind.Poiji;
import com.poiji.exception.PoijiExcelType;
import com.poiji.option.PoijiOptions;
import com.poiji.option.PoijiOptions.PoijiOptionsBuilder;

import org.apache.commons.io.IOUtils;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.util.*;
import java.util.function.Supplier;
import java.util.logging.Level;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.openntf.domino.*;
import org.openntf.domino.utils.Factory;
import org.openntf.domino.xsp.XspOpenLogUtil;

public class BatchChecker {
    private final String classID="::"
            + new Throwable().getStackTrace()[0].getClassName() + "::";
    @ExcelCellName("Material")
    String fusion;

    @ExcelCellName("Material Description")
    String prodName_Pack;

    @ExcelCellName("Batch")
    String batch;

    @ExcelCellName("Production date (PRK)")
    String prodDateSAP;

    @ExcelCellName("Prod.date (Molcom)")
    String prodDateWH;

    private Session ses;

    private Database db;

    private View view;
    private PrintWriter os;
    public BatchChecker() {
        ses = Factory.getSession();
        db = ses.getCurrentDatabase();
        view = db.getView("batches");
    }

    public <T> List<T> checking(InputStream inStream, Class<T> type){
        List<T> ret=new ArrayList<T>();
        Throwable throwable = new Throwable();
        try{
            XspOpenLogUtil.logEvent(throwable, this.classID + "<-"
                    + throwable.getStackTrace()[1].getClassName() + "."
                    + throwable.getStackTrace()[1].getMethodName()
                    +": Loading", Level.INFO,
                    null);

            List<BatchChecker> list=Poiji.fromExcel(inStream, PoijiExcelType.XLSX, BatchChecker.class);
                    //new File("wh-report.xlsx"), BatchChecker.class);
            XspOpenLogUtil.logEvent(throwable, this.classID
                    + throwable.getStackTrace()[1].getMethodName()
                    +": Loading has completed", Level.INFO,
                    null);
            XspOpenLogUtil.logEvent(throwable, this.classID
                    + throwable.getStackTrace()[1].getMethodName()
                    +": Searching...", Level.INFO,
                    null);
            for(BatchChecker el:list){
                ViewEntry entry=view.getFirstEntryByKey(el.batch,true);
                if (entry!=null)
                    ret.add(type.cast(el.batch));
            }
            XspOpenLogUtil.logEvent(throwable, this.classID
                    + throwable.getStackTrace()[1].getMethodName()
                    +": Searching has completed", Level.INFO,
                    null);

        }catch(Exception e){
            e.printStackTrace();
            XspOpenLogUtil.logError(e);
        }
        return (List<T>)ret;
    }
    
    public void checking(InputStream is, PrintWriter os, boolean exists){
        Throwable throwable = new Throwable();
        if (os !=null){
            this.os=os;
            //PoijiOptions options = PoijiOptionsBuilder.settings().sheetIndex(0).build();
            if (exists){
                XspOpenLogUtil.logEvent(throwable, this.classID
                        + throwable.getStackTrace()[1].getMethodName()
                        +": Creating list for existing batches...", Level.INFO,
                        null);
                Poiji.fromExcel(is, PoijiExcelType.XLSX, BatchChecker.class, this::dbCheck);//, options, this::dbCheck);
            }
            else{
                XspOpenLogUtil.logEvent(throwable, this.classID
                        + throwable.getStackTrace()[1].getMethodName()
                        +": Creating list for absent batches...", Level.INFO,
                        null);
                Poiji.fromExcel(is, PoijiExcelType.XLSX, BatchChecker.class, this::dbCheckNo);//, options, this::dbCheckNo);
            }
        }else{
            XspOpenLogUtil.logErrorEx(throwable, this.classID + "PrintWriter is null"
                    , Level.INFO, null);

        }
    }
    
    private void dbCheck(BatchChecker instance){
        Throwable throwable = new Throwable();
        //System.out.println("check batch: "+instance.batch);
        if (view.getFirstEntryByKey(instance.batch,true)!=null){
            os.write("="+instance.batch+";");
        }else{
            os.write(instance.batch+";");
        }

    }
    private void dbCheckNo(BatchChecker instance){
        if (view.getFirstEntryByKey(instance.batch,true)==null){
            os.write(instance.batch+";");
        }
    }
    
    ViewEntry getBatchEntry(String batch){
        return view.getFirstEntryByKey(batch,true);
    }
    
    static File createExcel(List<BatchChecker> list, String urlBase) throws IOException {
        File ret=File.createTempFile("out", ".xlsx");
        OutputStream os=new FileOutputStream(ret);
        Workbook wb= new XSSFWorkbook();
        Sheet sh=wb.createSheet("Batches");
        int i=0;
        for(BatchChecker el:list) {
            Row row=sh.createRow(i++);
            setCells(el, urlBase, row);
        }
        wb.write(os);
        wb.close();
        return ret;
    }
    
    private static void setCells(BatchChecker el, String urlBase, Row row){
        short cellIdx=0;
        Cell cell = row.createCell(cellIdx++);
        if (urlBase==null) {
            cell.setCellValue(el.batch);
            cell = row.createCell(cellIdx);
            cell.setCellValue(el.prodName_Pack);
        }else {
            cell.setCellValue(el.batch + ":" + el.prodName_Pack);
            Workbook wb = row.getSheet().getWorkbook();
            CellStyle hlink_style = wb.createCellStyle();
            Font hlink_font = wb.createFont();
            hlink_font.setUnderline(Font.U_SINGLE);
            hlink_font.setColor(HSSFColor.HSSFColorPredefined.DARK_BLUE.getIndex());
            hlink_style.setFont(hlink_font);
            CreationHelper creationHelper = wb.getCreationHelper();
            Hyperlink link = creationHelper.createHyperlink(HyperlinkType.URL);
            String url = urlBase + el.batch;
            link.setAddress(url);
            cell.setHyperlink(link);
            cell.setCellStyle(hlink_style);
        }
    }
    public void getBatch(String id){//, javax.servlet.http.HttpServletResponse response){
        Throwable throwable = new Throwable();
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ex = fc.getExternalContext();

        XspHttpServletResponse xspResponse = (XspHttpServletResponse) ex.getResponse();
        javax.servlet.http.HttpServletResponse response=xspResponse.getDelegate();

        if (id!=null && !id.isEmpty()){
            XspOpenLogUtil.logEvent(throwable, this.classID
                    + throwable.getStackTrace()[1].getMethodName()+"(): "
                    +"get first entry for: "+id, Level.INFO,
                    null);

            ViewEntry entry=getBatchEntry(id);
            
            
            //Document doc=db.getDocumentByUNID(id);
            if (entry!=null){
                String type=MIMEType.get("pdf");

                List<org.openntf.domino.EmbeddedObject> atts=entry.getDocument().getAttachments();
                //response.setContentType(type);
                response.setHeader("Content-Type",type);
                response.setHeader("Content-Disposition","attachment; filename="+atts.get(0).getName());
/*                XspOpenLogUtil.logEvent(throwable, this.classID
                        + throwable.getStackTrace()[1].getMethodName()+"(): "
                        +"mime type: "+type+"\n"
                        +"attach name: "+atts.get(0).getName(), Level.INFO,
                        null);
*/
                //File tmp=obj.createExcel(obj.testCheckingBC(), "");
                
                try {
                    IOUtils.copy(atts.get(0).getInputStream(),response.getOutputStream());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    XspOpenLogUtil.logError(e);
                }

            }else{
                XspOpenLogUtil.logEvent(throwable, this.classID
                        + throwable.getStackTrace()[1].getMethodName()+"(): "
                        +"entry hasn't found ", Level.INFO,
                        null);

            }
        }

    }

    public List<String> testChecking(){
        BatchChecker obj=new BatchChecker();
        return obj.checking(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("wh-report.xlsx"),String.class);
    }
    public List<BatchChecker> testCheckingBC(){
        BatchChecker obj=new BatchChecker();
        return obj.checking(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("wh-report.xlsx"),BatchChecker.class);
    }
    public void testCheckingOut(PrintWriter os){
        BatchChecker obj=new BatchChecker();
        obj.checking(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("wh-report.xlsx"),os, true);
    }
    
    public static void main(String args[]){
        BatchChecker obj=new BatchChecker();
        obj.checking(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("wh-report.xlsx"),String.class);
    }
}
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
бижуалвасик для хухеля (Excel)
Код:
Const XLSXtype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Const LINKBASE = "https://"& dominoServer & xsp & "?id"
Const checkService = xsp & "/BatchCheckService?exists=true"
Const adTypeBinary = 1
Dim authUrl As String

Public Sub test()
Dim Visibility As New Visibility
authUrl = "https://" & dominoServer & "/names.nsf?Login&Username=" _
                    & Replace(httpuser, " ", "%20", vbTextCompare) & "&Password=" & Password
Dim cookie As String
Dim response As Variant
Dim url As String
url = "https://" & dominoServer & checkService
'response = BinaryGetURL(authUrl, cookie)
'MsgBox cookie
Dim fileName As String
fileName = Application.ActiveWorkbook.FullName

response = HTTP_FileUpload(url, "POST")
FindAndAssignLink (response)
End Sub
Function FindAndAssignLink(ByRef arr As Variant)
    Dim Table As Range, sh As Worksheet, r As Range, i As Long
    Set sh = ThisWorkbook.Sheets(1)
    Set Table = sh.Cells
    For i = 2 To Table.CurrentRegion.Rows.Count
        Dim idx As Long
        If UBound(Filter(arr, "=" & Table.Cells(i, 3).Value2)) > -1 Then
            Table.CurrentRegion.Rows(i).Hyperlinks.Add Anchor:=Table.Cells(i, 1), Address:=LINKBASE & "=" & Table.Cells(i, 3).Value2
        Else
            Table.Cells(i, 1).Font.Color = vbRed
        End If
    Next
End Function
Function BinaryGetURL(url, ByRef cookie As String)
  'Create an Http object, use any of the four objects
  Dim Http
'  Set Http = CreateObject("Microsoft.XMLHTTP")
'  Set Http = CreateObject("MSXML2.ServerXMLHTTP")
  Set Http = CreateObject("WinHttp.WinHttpRequest.5.1")
'  Set Http = CreateObject("WinHttp.WinHttpRequest")

  'Send request To URL
  Http.Open "GET", url, False
  Http.send
  'Get response data As a string
  Set BinaryGetURL = Http
  cookie = Http.getResponseHeader("Set-Cookie")
End Function
'https://github.com/VBA-tools/VBA-JSON/blob/master/JsonConverter.bas
'https://raw.githubusercontent.com/VBA-tools/VBA-Dictionary/master/Dictionary.cls
Public Function HTTP_FileUpload(ByVal pUrl As String _
    , Optional ByVal pMethod As String = "GET" _
    , Optional fileName As String = "" _
    ) As Variant
    Dim strResponse As String

    On Error GoTo ErrorHandler
    Dim fileStream As Object

    Dim tmp As Workbook
    Set tmp = Workbooks.Add
    Dim current As Workbook
    Set current = ThisWorkbook
    current.Sheets(1).Copy Before:=tmp.Sheets(1)
    Application.DisplayAlerts = False
    tmp.SaveAs fileName:="tmp.xlsx" ', AccessMode:=xlExclusive, ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges
    fileName = tmp.FullName
    tmp.Close (True)
    Application.DisplayAlerts = True

    Set fileStream = CreateObject("ADODB.Stream")
    'fileStream.Mode = 1 ' //read
    fileStream.Type = adTypeBinary
    fileStream.Open
    fileStream.LoadFromFile fileName '"tmp.xlsx"

    Dim objHttp As Object
    'authorize
    Dim cookie As String
    Dim response As String
    Set objHttp = BinaryGetURL(authUrl, cookie)
    'Set objHttp = CreateObject("WinHttp.WinHttpRequest.5.1") 'CreateObject("MSXML2.XMLHTTP")
    objHttp.Open pMethod, pUrl, False
    'objHhttp.setRequestHeader "Authorization", "Basic " + Base64Encode(user + ":" + Password)

    objHttp.setRequestHeader "Content-Type", XLSXtype
    objHttp.setRequestHeader "Content-Length", fileStream.Size
    'objHttp.setRequestHeader "Cookie", cookie 'could use the same cookie
    objHttp.send fileStream.Read
    fileStream.Close

    strResponse = objHttp.responseText
    Dim JSON As Object ', JsonConverter As New JsonConverter
    Set JSON = JsonConverter.ParseJson(strResponse)
    Dim value As Variant
    value = JSON.Item("body")
    HTTP_FileUpload = Split(CStr(value), ";")

    MsgBox strResponse
    Set objHttp = Nothing
    Exit Function
ErrorHandler:
    MsgBox "Error - code is " & Err.Number & " - " & Err.Description
End Function
отправляет запрос с хухелем(с Excel файлом) на REST сервис, получает жсон, парсит, либы парснга по ссылкам со стековерфло и гитхаба
Dim Visibility As New Visibility - класс отключения рефрешей в хухеле
позже сделаю код для ЛО и ГуглДоксов
по полученному списку красит первую колонку в соответ. и делает линки на существующие ключи
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
код хэапги и реста на ней
XML:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex">
    <xp:this.afterRenderResponse><![CDATA[#{javascript:try{
  importPackage( com.setralubs);
  var exCon:javax.faces.context.ExternalContext = facesContext.getExternalContext();
//  var response:javax.servlet.http.HttpServletResponse = externalContext.getResponse();
  var response = exCon.getResponse().getDelegate();
  var batch=paramValues.get("id").toString();
  var batchChecker:BatchChecker=new BatchChecker
  batchChecker.getBatch(batch);//, response);
}catch(e){
  _dump(e);
  print("<<groupingreport.xsp>>"+e.toString());
  org.openntf.domino.xsp.XspOpenLogUtil.logError(e);
}
}]]></xp:this.afterRenderResponse>
    <xe:restService id="BatchCheckService" pathInfo="BatchCheckService"
        rendered="false" preventDojoStore="true" disableTheme="true">
        <xe:this.service>
            <xe:customRestService
                serviceBean="com.setralubs.BatchCheckService"
                contentType="application/json">
            </xe:customRestService>
        </xe:this.service>
    </xe:restService>
</xp:view>
getDelegate() - обязательно в таком варианте!
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
внезапно обнаружил
хотя уже задумывался про SmartNsf (уж больно простота создания сервиса подкупает)
теперь в нек раздрае ;)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
наверное все уже слышали про "волшебные" хидеры домины, есть ряд особенностей:
- после такой авторизации, домина выдает куки для юзера
- с этими куками, без хидера, нельзя авторизоваться (You are locked out) если юзер залочен
- эта авторизация плевать хотела на , т.е. заблоченный юзер сможет соединяться с сервером, если есть $WSRU в хидере (что хорошо и правильно)
- nginx не пропускает хидеры с $ , при обычных настройках (и это замечательно)

Т.о. описанные в предыдущих постах действия по авторизации нужны только в случае невозможности напрямую "говорить" с доминой (через хидеры)
- в целях сесуриту (security) - домина должна быть защищенной файрволом и реверс-прокси, если есть интеграция через HTTPEnableConnectorHeaders=1 (но ябы и без этой опции защищал ;) )
- для "таких" юзеров "надо" отдельный ACL на группу -WebPreAuthenticated- (как я понял она будет такая)
а еще есть такая штука timtripcony/oauth4domino
 
Последнее редактирование:
  • Нравится
Реакции: alexas1

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
передача $WSRU через (после версии 4.3)
Java:
    public DASUtilsBase() {
//--------------------- ЗАДАЕМ ЗАГОЛОВОК, String WebPreAuthenticated="$WSRU:approved_user";
        WSRU=WebPreAuthenticated.split(":",0);
        Header header = new BasicHeader(WSRU[0],WSRU[1]);
        List<Header> headers = new ArrayList();
        headers.add(header);[

        RequestConfig customizedRequestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY).build();
        //HttpClientBuilder customizedClientBuilder = HttpClients.custom().setDefaultRequestConfig(customizedRequestConfig);
        //---------------------здесь добавляем заголовки по-умолчанию
        HttpClientBuilder customizedClientBuilder = HttpClients.custom().setDefaultHeaders(headers).setDefaultRequestConfig(customizedRequestConfig);
        //https://stackoverflow.com/a/40982127 redirect strategy
        customizedClientBuilder.setRedirectStrategy(new MyDefaultRedirectStrategy());
        // Create the http client
        client = customizedClientBuilder.build();

        //client=HttpClients.createDefault();
        //set Authorization cookie
        try {
            //HttpGet get = new HttpGet(target+encBase64);
            HttpUriRequest get = RequestBuilder.get().setUri(serverURL+dbPart).build();
/*
            HttpGet get = new HttpGet(BaseURI + dominoServer+"/names.nsf?Login&Username="
                    +httpuser.replaceAll(" ","%20")+"&Password="+httppasswd);
*/
            HttpResponse response=client.execute(get);
            printResponseBodyToConsole(response);
        } catch (IOException ioe) {
            LOG.error("Unable to connect to '" + serverURL + "'");
            LOG.error(ioe.getMessage());
            System.exit(-1);
        }
важные откоментил //---------------------, SetHeader в такой конфигурации не нужен (не нужно лепить его в каждый запрос)
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 949
602
BIT
410
еще заметил интересный момент, не знаю как при др. вариантах аутентификации/аторизации, а в выше указанном, при допуске по авторизации к ресурсу, имеем заголовок last-modified
В случае запроса с сервера на авторизацию (сессионную через собственную форму или дефолтную) этого заголовка нет!
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!