impossible to send multipart/form-data - java

I made an application which received 2 parts: a picture and some text. The start of the code is:
#WebServlet("/App")
#MultipartConfig(fileSizeThreshold=1024*1024*10, // 10 MB
maxFileSize=1024*1024*50, // 50 MB
maxRequestSize=1024*1024*100) // 100 MB
public class App extends HttpServlet {
private static final long serialVersionUID = 205242440643911308L;
private static final String PREFIX = "stream2file";
private static final String SUFFIX = ".tmp";
private static final String UPLOAD_DIR = "uploads";
protected void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
JsonObject servletResponse = new JsonObject();
System.out.println("------------------------------");
System.out.println(req.getContentType());
System.out.println("------------------------------");
String text = null;
String uuid = UUID.randomUUID().toString();
Properties props = new Properties();
File dbPropsFile = new File("/config.properties");
FileReader fileReader = new FileReader(dbPropsFile);
props.load(fileReader);
for (Part part : req.getParts()) {
if(getFileType(part).equals("image")) {
The code fails on
for (Part part : req.getParts()) {
It works completely fine if I'm running it with mvn jetty:run, but when deployed to the server, it just crashes. Please help!!!
When trying to do System.out.println(req.getContentType()); this comes as null on the Tomcat and on the Jetty server, but it comes with the expected value on the mvn jetty:run

If the HttpServletRequest.getContentType() is null, then your request isn't satisfying the requirements for #MultipartConfig which requires the Content-Type value to be multipart/form-data
Ensure that your form is being submitted properly on the network first.
Perhaps add some unit tests to your project to ensure that the servlet is behaving as expected, allowing you to focus your attention on the form submit / request side.

Related

Change response based on query string in java servlet

Im having some trouble sending diffrenet response based on query string, I have 2 String that suppose to match a single param from the query names serviceType:
private static String restartQuery = "restarts";
private static String dbStatusQuery = "dbStatus";
And my doGet function needs to send response accordingly:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
String requestType = request.getParameter(serviceType);
// Set response content type
response.setContentType("text/html");
if(requestType.equals(restartQuery)){
//handle response for restartQuery
PrintWriter out = response.getWriter();
out.println("response for restart ....");
}else if (requestType.equals(dbStatusQuery)){
//handle response for dbStatusQuery
PrintWriter out = response.getWriter();
out.println("response for db ....");
}
}
The problem is that I get the same response(restart...), I had check the query string from the front-end - system.println(requestType) and they are different for each request, what can I change to make it work? if there is more code needed please comment below.
I have added 2 things based on comments here:
1- added consts to my defitions:
private static final String restartQuery = "restarts";
private static final String dbStatusQuery = "dbStatus";
2- check spaces from the front-end, just use a simple prefix check.
Thanks to all the helpers.

How to get the text from addTextBody in a MultipartEntityBuilder?

I am using an Android client to post data and some file in Google cloud storage:
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entityBuilder.addBinaryBody("file", file);
entityBuilder.addTextBody("author", author);
On the server side I am using a servlet to get that request.
However, while I am able to get the file and store it, I don't know how to get what's in the addTextBody (the "author" String in my case)
I have been searching for a while and just found someone that posted quite the same question but no one answered him. (How to get the text from a addTextBody in a miltipartentitybuilder)
Assuming you're using Servlet 3.0+, just use HttpServletRequest#getParts(). For example, if you wanted the content of the multipart part named author, you'd configure your servlet with #MultipartConfig, retrieve the appropriate Part object and consume its InputStream.
#MultipartConfig()
#WebServlet(urlPatterns = { "/upload" })
public class UploadServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Collection<Part> parts = req.getParts();
for (Part part : parts) {
if (!part.getName().equals("author"))
continue;
try (InputStream in = part.getInputStream()){
String content = CharStreams.toString(new InputStreamReader(in));
System.out.println(content); // prints the value of author
}
}
}
}

Facing issue while fetching data with "&" special characters

We have one screen/page in our application where we are showing different columns for different products. These all records in the columns are fetched from database.
Also, We have two export buttons at the bottom of the screen which is meant for showing all those records in the PDF and XLS format.
These functionalities are working fine except under one condition. We have one column name in the screen whose values are fetched from database. when any record under name column has & in it, the export functionality stopped working.
For example :-
for name "BOWOG BEHEER B.V.", the export is working fine for both pdf and xls.
But for the name "BOWOG & BEHEER B.V.", it stopped working. While clicking on export button, pdf and xls is showing as blank page.
Could anyone please help ?
Below is the piece of codes :- (not full code)
public class CVRExportServlet extends HttpServlet {
private final SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
/** context. */
private ResourceContext context = null;
private Map createParametersFromRequest(final HttpServletRequest request) {
// copy all request parameters
final Map parameters = new HashMap();
final Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
final String name = (String) names.nextElement();
final String[] values = request.getParameterValues(name);
if (values.length > 1) {
parameters.put(name, values);
} else {
parameters.put(name, values[0]);
}
}
// parse request uri to get type and format
final String requestURI = request.getRequestURI();
String type = StringUtils.left(requestURI, requestURI.lastIndexOf('.'));
type = StringUtils.substring(type, requestURI.lastIndexOf('/') + 1);
final String format = StringUtils.substring(requestURI, requestURI.lastIndexOf('.') + 1);
parameters.put(Constants.EXPORT_TYPE_PARAMETER, type);
parameters.put(Constants.EXPORT_FORMAT_PARAMETER, format);
// determine themeUrl
final String requestUrl = request.getRequestURL().toString();
final int index = requestUrl.indexOf(request.getContextPath());
String server = "";
if (index > -1) {
server = requestUrl.substring(0, index);
}
private void fillParameters(final HttpServletRequest request, final HttpServletResponse response, final Map parameters)
throws ApplicationException {
parameters.put("props", ResourceBundle.getBundle("messages"));
// Create search request using the search form
final SearchForm form = (SearchForm) request.getSession().getAttribute(
(String) request.getSession().getAttribute(CvrConstants.SESS_ATTR_CVR_SEARCH_FORM_NAME));
final SearchRequest searchRequest = form.getSearchRequest();
searchRequest.setPageNumber(1);
searchRequest.setRowsPerPage(10000);
parameters.put("searchRequest", searchRequest);
}
public void service(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
final long startTime = System.currentTimeMillis();
// create parameters from request
final Map parameters = this.createParametersFromRequest(request);
parameters.put(ResourceContext.class.getName(), this.context);
try {
this.fillParameters(request, response, parameters);
final SearchRequest searchRequest = (SearchRequest) parameters.get("searchRequest");
if (searchRequest == null || searchRequest.getCounterPartyList() == null
|| searchRequest.getCounterPartyList().isEmpty()) {
throw new ExportException("Exception occurred while handling export: empty counterparty list");
} else {
if (searchRequest.getCounterPartyList().size() == 1) {
this.handleSingleReportExport(response, parameters);
} else {
this.handleMutlipleReportExport(response, parameters);
}
}
} catch (final Exception e) {
this.handleException(e, request, response);
}
}
private void handleSingleReportExport(final HttpServletResponse response, final Map parameters) throws Exception {
final XmlExportService exportService = this.getXmlExportService();
final ApplicationContext context = this.getApplicationContext();
final XmlTransformationService xmlTransformationService = (XmlTransformationService) context.getBean("transformationService");
// perform export
exportService.export(parameters);
// perform transformation
final ExportResult exportResult = xmlTransformationService.transform(parameters);
// write result to stream
response.setContentType(exportResult.getContentType());
response.setContentLength(exportResult.getContentLength());
if (parameters.get("format").equals("csv")) {
response.setContentType("text/csv");
response.setHeader("Content-disposition", "attachment; filename=export.csv");
} else if (parameters.get("format").equals("pdf")) {
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "inline; filename=export.pdf");
}
final ServletOutputStream out = response.getOutputStream();
out.write(exportResult.getBytes());
out.flush();
out.close();
}
private void handleMutlipleReportExport(final HttpServletResponse response, final Map parameters) throws Exception {
final SearchRequest searchRequest = (SearchRequest) parameters.get("searchRequest");
response.setContentType("application/force-download");
response.setHeader("Content-Encoding" , "x-compress");
response.setHeader("Content-Disposition", "attachment; filename=export_" + parameters.get("format") + ".zip");
final XmlExportService exportService = this.getXmlExportService();
final ApplicationContext context = this.getApplicationContext();
final XmlTransformationService xmlTransformationService = (XmlTransformationService) context.getBean("transformationService");
// start the zip process
final ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
// create a file for each counterparty and add it to the zip file
for (final String counterPartyId : searchRequest.getCounterPartyList()) {
// make sure to reset the counterparty to the current one in the loop
searchRequest.setCounterPartyList(Arrays.asList(new String[] {counterPartyId}));
// perform export
exportService.export(parameters);
// perform transformation
final ExportResult exportResult = xmlTransformationService.transform(parameters);
// add the file to the zip
final String fileName = counterPartyId + "_" + sdf.format(searchRequest.getRevaluationDate()) + "." + parameters.get("format");
zos.putNextEntry(new ZipEntry(fileName));
zos.write(exportResult.getBytes());
zos.closeEntry();
}
// finish the zip process
zos.flush();
zos.close();
}
I have some idea now. actually the issue is there at vm (velocity template). The "name" column is fetched from vm file and code is something like this :-
$!{result.counterpartyName}
This is in for each loop for multiple records. Could anyone please suggest how can i ignore special characters in the vm file itself. so that we will be able to export correctly even if "name" column has "&" or "-" etc special characters.
It seems based on your code that you are using an XML transformation service.
I'd say it's probably your data in your parameters containing dangling & sign. To be valid XML ready for transformation, & should be &. However, based on the code given it is not possible to say where the XML data is coming from. You say it's coming from the database, so my guess is that the problem should be dealt with by modifying the data in the database.
Edit:
It seems I was partly right, but the database doesn't contain the XML - if I got this correctly, data is coming from database as raw tabular data, but is formatted to XML using velocity templates. If that's it, then XML escaping should be used in velocity template like this.

How to add a cookie using doTag method in custom tag?

I have developed a custom tag library in Java which I use in my web application.
I am not sure why but my doTag() is not setting up cookie at all. I have cleared my cache and restarted my computer as well. Here is the code:
public class UserVersionOfSite extends EvenSimplerTagSupport {
private static final Log logger = LogFactory.getLog(UserVersionOfSite.class);
private StringWriter sw = new StringWriter();
#Override
public void doTag() throws IOException, JspException {
getJspBody().invoke(sw); //get the tag body and put it in StringWriter object
//get request object to get cookie value
PageContext ctx = (PageContext)getJspContext();
HttpServletRequest httpServletRequest = (HttpServletRequest) ctx.getRequest();
HttpServletResponse httpServletResponse = (HttpServletResponse) ctx.getResponse();
if(httpServletRequest.getParameterMap().containsKey("show_full_site")) {
logger.debug("show_full_site ");
if(!checkIfCookieExists(httpServletRequest)){
Cookie cookie = new Cookie("SHOW_FULL_SITE",httpServletRequest.getParameter("show_full_site"));
cookie.setMaxAge(86400);
httpServletResponse.addCookie(cookie);
//write the tag output
if(!httpServletRequest.getParameter("show_full_site").equalsIgnoreCase("true")){
//write the response
getJspContext().getOut().println(sw.toString());
}
}else{
String cookieValueString = getCookieValue(httpServletRequest.getCookies(),"SHOW_FULL_SITE","false");
if(!cookieValueString.equalsIgnoreCase("true")){
//write the response
getJspContext().getOut().println(sw.toString());
}
}
}
}
#Override
public String getResult() throws IOException {
return "User version of site";
}
public String getCookieValue(Cookie[] cookies,
String cookieName,
String defaultValue) {
for(int i=0; i<cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName()))
return(cookie.getValue());
}
return(defaultValue);
}
public boolean checkIfCookieExists(HttpServletRequest httpServletRequest){
logger.debug("inside checkIfCookieExists()");
boolean cookiePresent = Arrays.asList(httpServletRequest.getCookies()).contains( "SHOW_FULL_SITE" );
return cookiePresent;
}
}
Even I tried adding the code without using if else statements but still no success. Is there any thing critical I am missing?
Any ideas guys??!!! I have checked the browser's setting as well, but there is nothing there which is blocking a creation of cookie!
I realise the horse has probably bolted by the time I'm posting this but, for the benefit of others stumbling across it, I think the problem may be related to the feature of RequestDispatcher highlighted in this question: unable to add a cookie included in JSP via jsp:include
your following line inside checkIfCookieExists() method is wrong:
Arrays.asList(httpServletRequest.getCookies()).contains( "SHOW_FULL_SITE" );
HttpServletRequest.getCookies() returns Cookie[]. You are wrapping it inside a List and checking for a string "SHOW_FULL_SITE" inside this.
Coming back to your question- how do you know cookie is not being set in the HTTP headers? Try using browser plugins like firebug to see the HTTP response headers coming from server. Also set the path of cookie before adding it to response e.g.
Cookie cookie = new Cookie("SHOW_FULL_SITE",httpServletRequest.getParameter("show_full_site"));
cookie.setMaxAge(86400);
cookie.setPath("/");

More URL options HttpServletRequest

I pass parameters to the server line
"login=testAva4&nick=testAvaNick&social=vk&saurl=http://domain.example?param1=1&param2=2&param3=3&maurl=1"
waiting as the value saurl="http://domain.example?param1=1&param2=2&param3=3"
but i get http://domain.example?param1=1 and param2=2 param3=3
From Eclipse debug
req->_parameters
{maurl=1, nick=testAvaNick, param2=2, saurl=http://domain.example?param1=1, param3=3, social=vk, login=testAva4}
Gets the parameters in the code like this:
public class AddProfileServlet extends PlacerServlet {
//Add new profile method
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//Receive variables from URL
String login = req.getParameter("login");
String nick = req.getParameter("nick");
String social = req.getParameter("social");
String saurl = req.getParameter("saurl");
You should use URLEncoding on the saurl parameter.
Look at URLCodec at the commons codec enter link description here project.
I don't think you will need to encode the entire parameters part, but just the value for this specific parameter.
You can encode a string using:
URLCodec codec = new URLCodec();
String encodedValue = codec.encode(valueToEncode);
And you should use encodedValue as the value passed to the saurl parameter.

Categories

Resources