Friday, August 24, 2018

ServletOutputStream byte array to pdf corrupt pdf

I use tomcat 7.0.53, Struts 1.2.7, Spring 3.1.1. This is my code:

File file = new File("C:\\pdf\\" + report.getFileName());
FileOutputStream fos = new FileOutputStream(file);
fos.write(report.getData());
fos.close();

response.addHeader("Content-disposition", "application; filename="
                    + report.getFileName());
response.setContentType("application/pdf");
response.setContentLength(report.getData().length);

ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(report.getData());
outputStream.flush();

The file I get is right no problem there. But the file I get from response is corrupted. I tried to set encoding to response, tried to turn on spring CharacterEncodingFilter, tomcats SetCharacterEncodingFilter. Nothing helps. Where should I look at? p.s. this code is in Struts Action execute method

Solved

you might want to save the result that you get from your webserver and compare it with the correct pdf. This way you'll see if there are some extra bytes at beginning or end, differences in encoding or whatever else is different.


Remove response.setContentLength(report.getData().length); and try if it works, by doing this you also enable chunked data transmission.


I needed to return a null instead of an ActionForward so Struts knows the response was handled within the action.


I had the similar issue - corrupted binary pic. upon the download. Then while downloading TXT/XML files, I have noticed few blank lines at the beginning the text body.

Using the suggestion above on JSP, I removed all line breaks in my JSP page which manages the download. So all jsp and server tags follow in one single line:

<%..response.  ;response.setStatus(HttpServletResponse.SC_RESET_CONTENT);return; %>

This removed extra blank lines in TXT/XML and solved binary corruption issue as well.

Olaf, thank you for the clue


Monday, August 20, 2018

SSIS complex xml multiple outputs priority

I have xml files with data in the format:


  
    
  
  
    
  
 

etc

Trying to import this as a complex xml using SSIS but I need the data in the parent element attributes to be imported first, so that foreignkey constraints are complied with.

Prior to the xml import source routine I used SSIS SQL data task to obtain the highest/last id for the parent level xml's corresponding table. I then apply that value +1 to a variable (call it ParentId) which is used for all child tables in their foreignkey fields.

Then all of the xml source outputs are mapped to tables, including the xml parent level and corresponding table. I'm relying on this insert to create the id that I am assuming (i.e. the one I have assigned to the variable ParentId)

But the import fails because the parent output is not being processed first, so it never inserts that record and the parentid I am assuming is never generated.

Is there a way to enforce a priority or order that the xml source outputs are processed?

Solved

In case this helps anyone else.

What I did in the end is to use an xml task (xslt) to split the file into two, one for the parent and then another for the child records (the parent is always only one record).

Then I created two xml sources in sequence, first one imports the newly created parent xml, and using the same query & validation method mentioned in the first post obtains the correct identity value.

This is then used across all the child records in the second xml source task.


Sunday, August 19, 2018

CLS vs .NET type compliance: understanding the difference

I'm missing something here. I get that one would use .NET compliant types in public interfaces and methods so that .NET languages can play nicely together (for example, "System.String", not C#'s "string").

If one uses .NET compliant types, then surely all .NET based languages can inter-operate. When and how does CLS compliance factor in?

For example, System.UInt16 is .NET-compliant, not CLR-compliant, and equivalent to "ushort" in C#.

Solved

I get that one would use .NET compliant types in public interfaces and methods so that .NET languages can play nicely together (for example, "System.String", not C#'s "string").

That is actually not an issue. Using C#'s string will result in exactly the same CIL as using System.String.

When and how does CLS compliance factor in?

Some languages do not support all types, so CLS compliance is required if you want to support the type system that is going to work cleanly in all languages. This means that ushort (System.UInt16) is not guaranteed to be usable by all .NET languages, so you should avoid exposing it in a public type if you want to be CLS compliant.

There are other rules you need to follow for CLS compliance, such as not differentiating members merely by case, as some languages are not case sensitive. The type requirements are merely one of many requirements for full CLS compliance.

The main issue here is that the common .NET languages (such as C#) allow you to use many types, names, and techniques that aren't guaranteed to be available to ALL CLS compliant languages - C# is more flexible than it a language needs to be for CLS compliant. This means that, when you use C# to write code, if you want that code to be usable by all CLS compliant languages, you need to restrict what you expose in public APIs.


CLS compliance is stricter than just the shared types system (meaning the types that all .NET language can use).

One example is naming - in C# you can start a public member name with an _.

This is not CLS compliant, as not all languages allow it.


If one uses .NET compliant types, then surely all .NET based languages can inter-operate.

That's not at all true. Not all languages support all of the .NET types. For example, earlier versions of VB.NET didn't support UInt16, UInt32, or UInt64.

When and how does CLS compliance factor in?

The CLS defines, among other things, the types that languages must implement in order to interoperate. All other types are optional.


Saturday, August 18, 2018

Quicksort String Vector Alphabetically

I was having trouble with my code. I pass in an array of strings (names) and I want to do a quick sort and sort them alphabetically. Then, what I would like to do is with my array of years and ages, is swap those values respectively with the values swapped in my names array. However, I'm having trouble trying to implement that.

In the main function, I pass in:

quicksort(names, names[0], names[names.size() - 1]);

And in that code contains

void quicksort(vector &names, string min, string max){
cout << "\n\tSorting names...\n";

int             temp = 0, 
                i = 0;

string          lowMin = max,
                lowMax = min,
                highMin = max,
                highMax = min,
                pivot;

vector  below, 
                above;

if (min != max){

    pivot = (max[i] + min[i]) / 2;

    while (temp < names.size()){
        if (names[temp] <= pivot){
            if (lowMax.compare(names[temp]) < 0){
                lowMax = names[temp];
            }

            if (lowMin.compare(names[temp]) > 0){
                lowMin = names[temp];
            }

            below.push_back(names[temp]);

        }
        else {
            if (highMax.compare(names[temp]) < 0){
                highMax = names[temp];
            }

            if (highMin.compare(names[temp]) > 0){
                highMin = names[temp];
            }

            above.push_back(names[temp]);
        }
        temp++;
    }

    if ((below.size() > 1) && (names.size() != below.size())){
        quicksort(below, lowMin, lowMax);
    }
    if ((above.size() > 1) && (names.size() != above.size())){
        quicksort(above, highMin, highMax);
    }
    for (size_t i = 0; i < below.size(); i++){
        names[i] = below[i];
    }
    for (size_t i = below.size(); i < names.size(); i++){
        names[i] = above[i - below.size()];
    }

    }

} // // End quicksort()

In this case, would it be better to make a swap function and send in two integers so I can swap values in my other vector arrays? For example, I was thinking swapValue(int i, int j){ /* do something */} Also, can someone explain to me the difference between foobar[i].swap(foobar[j]) and swap(foobar[i], foobar[j])? Are these methods more efficient than say creating a temp variable and swapping values?

Solved

Don't implement quicksort if you do it only because you need some sorting algorithm to use.

You seem to have three std::vector for name, age and year, where elements at the same position are related. Why not combine everything?

struct Person //or some name
{
    std::string name;
    int age;
    int year;

    int operator<(const Person &other) //comparison
    {
        return name.compare(other.name);
    }
};

Of course, you could make a full class with the Big5 etc. too, if you want.

Now, with a vector v;, you can use std::sort:

std::sort(v.begin(), v.end());

That's all.

...If you still want to have a quicksort function, take eg. this, and change the lines with the swaps so that swaps are made on all three vectors.

About your other question:

The swap of std::string and the independent function swap with string paramters do the same thing (technically they don't have to, they are completely independent, but they do).

And why swap(a,b) is better than c=a;a=b;b=c;:

In the second code, values are copied three times. For std::string, this means three times allocating new memory and copying the whole content. Swap can do it without any content copy (it can access the internal pointers etc. and exchange only these).