пятница, 5 июля 2013 г.

Exporting Excel spreadsheet from Spring MVC application.

Here I will provide solution for common situation, when you need to export some kind of Excel doc (e.g. report) from web application built on Spring MVC framework. It's made with help of Apache POI library, which generates spreadsheet.

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.springframework.web.servlet.view.document.AbstractExcelView;

/**
 * @author Maxim Baev
 */
public class ExcelRecipeWishListView extends AbstractExcelView {

 @Override
 protected void buildExcelDocument(Map model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {
  Map productMap = (Map) model.get("productMap");
  //create a wordsheet
  HSSFSheet sheet = workbook.createSheet("Product list");

  HSSFRow header = sheet.createRow(0);
  CellStyle cellStyle = workbook.createCellStyle();
  Font font = workbook.createFont();
  font.setBoldweight(Font.BOLDWEIGHT_BOLD);
  cellStyle.setFont(font);
  Cell headerCell1 = header.createCell(0);
  headerCell1.setCellStyle(cellStyle);
  headerCell1.setCellValue("Product");
  Cell headerCell2 = header.createCell(1);
  headerCell2.setCellStyle(cellStyle);
  headerCell2.setCellValue("Quantity");

  int rowNum = 1;
  for (Map.Entry entry : productMap.entrySet()) {
   //create the row data
   HSSFRow row = sheet.createRow(rowNum++);
   row.createCell(0).setCellValue(entry.getKey());
   row.createCell(1).setCellValue(entry.getValue());
  }
  response.setHeader("Content-Disposition", "attachment; filename=\"product_list.xls\"");
 }
}

In Spring config spring-excel-views.xml it should be declared like that:

    
    

Then used in main config:

        

And finally on your controller:
    @RequestMapping(value = "/xls_wish_list")
    public ModelAndView exportWishListToExcel(HttpSession session) {
        List recipes = null;
        Map productMap = null;
        if (session.getAttribute("recipeIds") != null) {
            Set recipeIdSet = (Set) session.getAttribute("recipeIds");
            List recipeIds = new ArrayList(recipeIdSet);
            List searchCriteria = new ArrayList(1);
            searchCriteria.add(new IdSearchCriterion(recipeIds));
            recipes = recipeService.getRecipes(searchCriteria);

            productMap = makeProductMap(recipes);

        }
        //return excel view
        Map model = new HashMap(1);
        model.put("productMap", productMap);
        return new ModelAndView(new ExcelRecipeWishListView(), model);
    }

вторник, 26 февраля 2013 г.

Spring MVC form validator example

Here I provide and example of custom validation of a form fields, made with Spring MVC framework.

import com.baev.cook365.model.Recipe;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

/**
 * Created by Maxim Baev.
 */
public class RecipeValidator implements Validator {

    @Override
    public boolean supports(Class aClass) {
        return Recipe.class.equals(aClass);
    }

    @Override
    public void validate(Object o, Errors errors) {
        Recipe recipe = (Recipe) o;
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "recipe.title", "fill-in-the-name", "Is required");
    }
}

пятница, 11 января 2013 г.

JSF custom converter

Example of rather simple JSF converter to transform string with separated by semicolon words to the list of strings. In my case it was useful for mailbox application for email address input field with multiple email addresses.
/**
 * Custom converter to transform input string value to the list of strings.
 *
 * @author Maxim Baev
 */
@FacesConverter(value = "stringListConverter")
public class StringListConverter implements Converter {

    private static final Logger LOGGER = LoggerFactory.getLogger(StringListConverter.class);

    private static final String DELIMITER = ";";
    private static final String WHITESPACE = " ";

    /**
     * {@inheritDoc}
     */
    @Override
    public Object getAsObject(final FacesContext context, final UIComponent component, final String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        try {
            return Arrays.asList(value.replaceAll(WHITESPACE, StringUtils.EMPTY).split(DELIMITER));
        } catch (Exception e) {
            LOGGER.error("Failed to convert string to list", e);
            throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to list", value)), e);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getAsString(final FacesContext context, final UIComponent component, final Object value) {
        if (!(value instanceof List)) {
            return null;
        }

        return StringUtils.join((List) value, DELIMITER + WHITESPACE);
    }
}


пятница, 18 мая 2012 г.

Oracle XE: changing HTTP port

To change default http port used by Oracle XE all you need is execute simple command. Run SQL Command line:

SQL> connect
Enter user-name: system
Enter password:
Connected.
SQL> exec dbms_xdb.sethttpport(8088); // or any other port you want

PL/SQL procedure successfully completed.

SQL> quit

That's it!

вторник, 31 января 2012 г.

Running executable jar file in windows vista or windows 7

In Windows Vista or Windows 7 the manual file association editor has been removed. So you can have problems with running executable jar by double-clicking it. You can solve it in different ways:
1) Most easiest way is to use program Jarfix
2) Also you can add file association in your command prompt window using "Run as administrator”:
          C:\>assoc .jar=jarfile
          C:\>ftype jarfile="C:\path\to\your\javaw.exe" -jar "%1" %*

среда, 25 января 2012 г.

Resolving problems with running Apache Nutch on Windows. Part 2.

When Nutch crawling process started with '-solr' argument you can face a problem with Solr schema.xml.Some fields can be absent and you will see errors in log:
2012-01-25 11:03:46,484 WARN  mapred.LocalJobRunner - job_local_0020
org.apache.solr.common.SolrException: ERROR: [doc=http://business.ngs.ru/] unknown field 'content'

ERROR: [doc=http://business.ngs.ru/] unknown field 'content'

request: http://localhost:8983/solr/update?wt=javabin&version=2
    at org.apache.solr.client.solrj.impl.CommonsHttpSolrServer.request(CommonsHttpSolrServer.java:436)
    at org.apache.solr.client.solrj.impl.CommonsHttpSolrServer.request(CommonsHttpSolrServer.java:245)
    at org.apache.solr.client.solrj.request.AbstractUpdateRequest.process(AbstractUpdateRequest.java:105)
    at org.apache.solr.client.solrj.SolrServer.add(SolrServer.java:49)
    at org.apache.nutch.indexer.solr.SolrWriter.close(SolrWriter.java:93)
    at org.apache.nutch.indexer.IndexerOutputFormat$1.close(IndexerOutputFormat.java:48)
    at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:474)
    at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:411)
    at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:216)



To fix this I've copied schema.xml for Solr from http://svn.apache.org/viewvc/nutch/branches/branch-1.4/conf/schema.xml?view=markup.

вторник, 24 января 2012 г.

Resolving problems with running Apache Nutch on Windows. Part 1.

First root of some problems with running Apache Nutch on Windows is Cygwin, as Nutch has bash scripts to run. So, install Cygwin and add its root directory to 'path' system variable (e.g. C:\Cygwin). But if you added only root directory to path you can see exception in Nutch log:

java.io.IOException: Expecting a line not the end of stream
    at org.apache.hadoop.fs.DF.parseExecResult(DF.java:109)
    at org.apache.hadoop.util.Shell.runCommand(Shell.java:179)
    at org.apache.hadoop.util.Shell.run(Shell.java:134)
    at org.apache.hadoop.fs.DF.getAvailable(DF.java:73)
    at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:329)
    at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:124)
    at org.apache.hadoop.mapred.MapOutputFile.getSpillFileForWrite(MapOutputFile.java:107)
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1221)
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:1129)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:359)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:307)
    at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:177)


To resolve this you should add Cygwin 'bin' directory to your system path (e.g. C:\Cygwin\bin)