I’m trying to upload an excel in servlet and process it. While uploading I set enctype=“multipart/form-data” in my form. But in my servlet .isMultiPart(request) returns false.
JSP code:
function fSubir()
{
fFreezeButtons();
this.document.forms[0].action="../servlet/renault.saf.demandepiece.demandes.servlet.AjouterPoste";
if (this.document.forms[0].Flag.value == "1")
{
this.document.forms[0].Flag.value = "0";
this.document.forms[0].submit();
}
}
Select .xlsx type File :
<input type="submit" value="upload" onclick="fSubir()"/>
My .Jsp also has another form of get method which doesn’t have any enctype.
Servlet code;
public class AjouterPoste extends SapprServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
private final String UPLOAD_DIRECTORY = "/appli01/safdev01/saf_cl2/test/";
public void performTask(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
System.out.println("inside the AjouterPoste class - performTask");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
System.out.println("Inside doPost:"+isMultipart+":"+request);
Please find the parts of my code on which I’m trying to upload a file.
When you submit a form having multipart/form-data, you can't use request.getParameter(paramName). Instead use the code below (part of the Apache FileUpload library)
try {
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
// this part is used instead of request.getParameter
String fieldName = item.getFieldName();
String fieldValue = item.getString();
// do something here
} else {
// this is the file processing part
String fieldName = item.getFieldName();
String fileName = FilenameUtils.getName(item.getName());
InputStream fileContent = item.getInputStream();
...
}
}
} catch (FileUploadException e) {
throw new ServletException("exception", e);
}
You can tell that a specific item is a regular form item (and not a file) by checking that FileItem.isFormField() method returns true.
Related
I get the json value using the retrofit library at application launch and I want to send it to the global variable in the class. How can I do it?
Domain is coming, I can see it on the screen with toast message
public void onCreate() {
setRetrofitSettings();
}
public void setRetrofitSettings(){
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
timeApi = retrofit.create(TimeApi.class);
timeTurkeyCall = timeApi.getTime();
timeTurkeyCall.enqueue(new Callback<TimeTurkey>() {
#Override
public void onResponse(Call<TimeTurkey> call, Response<TimeTurkey> response) {
if (response.isSuccessful()){
timeTurkey = response.body();
Global.APIURL = String.valueOf(timeTurkey.getDateTime());
// I want to send the value here.
}
}
#Override
public void onFailure(Call<TimeTurkey> call, Throwable t) {
System.out.println(t.toString());
}
});
}
I want to send post value to global class
I want the incoming data to be assigned to the API_URL variable from here
public class Global {
public static final String API_URL;
}
I want the incoming domain to be active as long as the application is open.
I want to pass the url of a webpage containing a <span id="spanID"> value </span> tag to a method like setTextBoxText(string url, string id) which is written in a wpf application codeBehind (MainWindow.xaml.cs) and set the Text of a specific TextBox Control to the span value, without loading the webpage. (for Ex. tracking price of a product in amazon)
I prefer to execute JavaScript code to get value of html elements and set the content of wpf controls to the result of the js code (function)
something like this:
public partial class MainWindow : Window
{
string url = "https://websiteaddress.com/rest";
setTextBoxText(url, "spanID");
static void setTextBoxText(string url, string id)
{
// code to get document by given url
txtPrice.Text = getHtmlElementValue(id);
}
string getHtmlElementValue(string id)
{
// what code should be written here?
// any combination of js and c#?
// var result = document.getElementById(id).textContent;
// return result;
}
}
You can use the HttpClient to load the HTML content of an URL and then process the DOM object in a JavaScript like syntax by wrapping the response into a mshtml.HTMLDocument - requires reference to Microsoft.mshtml.dll:
private mshtml.HTMLDocument HtmlDocument { get; set; }
private async Task SetTextBoxTextAsync(string url, string id)
{
await UpdateHtmlDocumentAsync(url);
var value = GetHtmlElementValueById(id);
txtPrice.Text = value;
}
public async Task UpdateHtmlDocumentAsync(string url)
{
using (HttpClient httpClient = new HttpClient())
{
byte[] response = await httpClient.GetByteArrayAsync(url);
string httpResponseText = Encoding.GetEncoding("utf-8").GetString(response, 0, response.Length - 1);
string htmlContent = WebUtility.HtmlDecode(httpResponseText);
this.HtmlDocument = new HTMLDocument();
(this.HtmlDocument as IHTMLDocument2).write(htmlContent);
}
}
public string GetHtmlElementValueById(string elementId)
=> this.HtmlDocument.getElementById(elementId).innerText;
I'm dealing with a HttpSessionRequiredException and read about (https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc) how to catch it via the #ExceptionHandling annotation.
This does work since my breakpoint hits the spot. Unfortunately the string containing the view name does not trigger any view resolving and therefore no error page is being rendered.
Steps to Reproduce:
Open http://localhost:8080/manager (Session Attributes are being initialized)
Restart Web Application (Session/SessionAttributes are being reset)
Fill out form and press button (launches POST Request via AJAX - see Edit #2)
ExceptionHandler jumps in. Since a HttpSessionRequiredException is being thrown due the missing session attributes
Check Network Panel in Chrome which yields following information on the failed POST:
Controller Class incl. Exception Handler
#Controller
#Log
#RequestMapping(value = "/manager")
#SessionAttributes({"moduleDescriptors", "Environments", "moduleExecutionData"})
public class ManagerController {
private static final String MANAGER_VIEW = "manager";
private final ManagerHelper managerHelper;
private final ModuleExecution moduleExecution;
private final SystemProperties SystemProperties;
#Autowired
public ManagerController(ManagerHelper managerHelper, ModuleExecution moduleExecution,
SystemProperties SystemProperties) {
this.managerHelper = managerHelper;
this.moduleExecution = moduleExecution;
this.SystemProperties = SystemProperties;
}
#GetMapping
public ModelAndView render() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName(MANAGER_VIEW);
modelAndView.addObject("moduleExecutionData", new ModuleExecutionData());
List<ModuleDescriptor> moduleDescriptorsFromServices = managerHelper.getModuleDescriptorsFromServices();
modelAndView.addObject("moduleDescriptors", moduleDescriptorsFromServices);
//TODO: Change varName for Systems
modelAndView.addObject("Environments", SystemProperties.getEnvironments());
log.info("Found " + moduleDescriptorsFromServices.size() + " module descriptors");
return modelAndView;
}
#PostMapping
public String execute(#ModelAttribute ModuleExecutionData moduleExecutionData) {
moduleExecution.execute(moduleExecutionData);
// sessionStatus.setComplete();
return MANAGER_VIEW;
}
#ExceptionHandler(HttpSessionRequiredException.class)
public String sessionError(){
return "sessionError";
}
}
My view lies within all the folder with all working views.
Any idea what I'm doing wrong? I'm configuring spring completely with annotations - not XML.
Edit:
I checked the response and saw that it actually returns the HTML of the View. But this HTML is not rendered. Is it because I made a POST request? Which actually ignores any return HTML?
But that does not make sense - because my original PostHandler does return a view as well and it is rendered.
PostHandler
#PostMapping
public String execute(#ModelAttribute ModuleExecutionData moduleExecutionData) {
moduleExecution.execute(moduleExecutionData);
return MANAGER_VIEW;
}
Edit #2
Here is the POST JavaScript Ajax logic
function postForm(event) {
const moduleId = $(event.currentTarget).data("module-id");
const formData = $("#" + moduleId).serialize();
$.ajax({
type: "post",
data: formData,
url: "/manager",
dataType: "json"
});
}
I have a servlet that gets parameters from an HTML dropdown page. On button click the data is sent to the servlet. It works the first time the data is sent, but if I stay on the page and select a different value from the dropdown
and click the submit button, the new data is not set into the session variable.
My servlet is below. Do I need to modify the DoGet method? Again, it works the first time but the session variable doesn't change afterwards.
#WebServlet("/ListStudentServlet")
public class ListStudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ListStudentServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String sessid = request.getParameter("studentid");
ArrayList<FactStudentDataBean> result = new ArrayList<>();
try ( Connection con = JdbcUtil.getConnection()) {
String sql= "select F.Sessionid "
+ "from FACT_STUDENT F "
+ "where studentid = '"+sessid+"';";
try (Statement st = con.createStatement()) {
ResultSet rs = st.executeQuery(sql);
while (rs.next()){
result.add(new FactStudentDataBean(rs.getString(1)));
}
for (FactStudentDataBean factStudentDataBean : result) {
sessid = factStudentDataBean.getSessid();
}
} catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
//Trying to set the session variable below, works the first time but anything after doesn't change
HttpSession session = request.getSession(true);
session.setAttribute("sessid", sessid);
}
}
Your code is a little bit "dirty". First of all: why you are writing this sql query like this?:
String sql= "select F.Sessionid "
+ "from FACT_STUDENT F "
+ "where studentid = '"+sessid+"';";
and not like this?:
String sql= "select F.Sessionid from FACT_STUDENT F where studentid = '"+sessid+"';";
Second: Always try to use prepareStatement instead of createStatement (for explanation of what i am telling please see this question:prepareStatement vs executeStatement)
And for the answer now: Ithink you must use session.getAttribute("sessid", sessid);
Check the jsessionid values you are getting on server side. If both are different then try to get session by passing false instead of true.
request.getSession(false);
Also goto tomcat manager application and monitor active sessions.
Hope this will help.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Would that be the right approach? If so, how should I implement it in Java?
An elegant way of doing this would be to implement an XMLReader that can read the CSV file line by line (using a BufferedReader) to output the corresponding SAX events. Then use this CSV parser and the generated events as a stream source to dynamically build the XML result through an empty XSL transformation. This way everything will be treated as a stream and your program will be able to handle very large documents without encountering performance issue. Also, you'll show your understanding of subjacent parsing SAX standards and streaming concepts.
Here is a great example of this kind of implementation: http://mobile.developer.com/xml/article.php/2108031/Transforming-Flat-Files-To-XML-With-SAX-and-XSLT.htm (with a "properties" file as source instead of a CSV).
If performances (or handling big documents) aren't an issue, a simple BufferedReader that directly parses the CSV file line by line and creates a Document in RAM using DocumentBuilder.newDocument() will be a simpler way to get the job done "the DOM way".
https://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilder.html
Here is a complete example :
SAXExample.java (the useful part of the code)
public class SAXExample {
public static void main(String[] args) {
try (InputStream is = SAXExample.class.getResourceAsStream("/demo.csv");
InputStream transformerInputStream = SAXExample.class
.getResourceAsStream("/echo.xsl")) {
XMLReader reader = new CSVFileParser();
reader.setContentHandler(new DefaultHandler());
TransformerFactory factory = TransformerFactory.newInstance();
SAXTransformerFactory saxTransFact = (SAXTransformerFactory) factory;
TransformerHandler transformerHandler = saxTransFact
.newTransformerHandler(
new StreamSource(transformerInputStream));
transformerHandler.setResult(new StreamResult(System.out));
reader.setContentHandler(transformerHandler);
reader.parse(new InputSource(is));
} catch (Exception e) {
e.printStackTrace();
}
}
public static class CSVFileParser extends AbstractXMLReader {
private static final Attributes EMPTY_ATTR = new AttributesImpl();
#Override
public void parse(InputSource input) throws IOException, SAXException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(input.getByteStream()));
String buffer = null;
ContentHandler handler = getContentHandler();
if (handler == null)
return;
handler.startDocument();
while ((buffer = reader.readLine()) != null) {
String content = buffer.substring(buffer.indexOf(",") + 1,
buffer.lastIndexOf("\""));
if (buffer.startsWith("\"open,")) {
handler.startElement("", content, "", EMPTY_ATTR);
} else if (buffer.startsWith("\"close,")) {
handler.endElement("", "", content);
} else {
char[] chars = content.toCharArray();
handler.characters(chars, 0, chars.length);
}
}
handler.endDocument();
}
}
}
AbstractXMLReader.java (utility class to simply implements an XMLReader) :
public abstract class AbstractXMLReader implements org.xml.sax.XMLReader {
private Map<String, Object> featureMap = new HashMap<String, Object>();
private Map<String, Object> propertyMap = new HashMap<String, Object>();
private EntityResolver entityResolver;
private DTDHandler dtdHandler;
private ContentHandler contentHandler;
private ErrorHandler errorHandler;
public abstract void parse(InputSource input)
throws IOException, SAXException;
public boolean getFeature(String name)
throws SAXNotRecognizedException, SAXNotSupportedException {
Boolean featureValue = (Boolean) this.featureMap.get(name);
return (featureValue == null) ? false : featureValue.booleanValue();
}
public void setFeature(String name, boolean value)
throws SAXNotRecognizedException, SAXNotSupportedException {
this.featureMap.put(name, new Boolean(value));
}
public Object getProperty(String name)
throws SAXNotRecognizedException, SAXNotSupportedException {
return this.propertyMap.get(name);
}
public void setProperty(String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException {
this.propertyMap.put(name, value);
}
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
public EntityResolver getEntityResolver() {
return this.entityResolver;
}
public void setDTDHandler(DTDHandler dtdHandler) {
this.dtdHandler = dtdHandler;
}
public DTDHandler getDTDHandler() {
return this.dtdHandler;
}
public void setContentHandler(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
public ContentHandler getContentHandler() {
return this.contentHandler;
}
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
public ErrorHandler getErrorHandler() {
return this.errorHandler;
}
public void parse(String systemId) throws IOException, SAXException {
parse(new InputSource(systemId));
}
}
echo.xsl (the "empty" XSLT transformation to only output the original XML as generated by our custom parser)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes" />
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Using this class with your example output the following :
<?xml version="1.0" encoding="UTF-8"?><story>
<id>1234</id>
<snaps>
<snap/>
<snap/>
<snap/>
<snap/>
</snaps>
</story>
The CSV Parser is a "quick & dirty" implementation that does not really implements the full CSV specifications, but only your needs.
I think understanding these XML parsing and XSL transformation concepts were the goals of this exercise.