Asked  7 Months ago    Answers:  5   Viewed   87 times

After submitting data in the HTML from, a servlet adds these data to my DB and forwards a result message to a JSP page. I want to retain the initially submitted values in the form after the forward.

Is it sensible to make an object in a servlet and add all the parameters I receive and send it with a request to JSP? Is there another better way?

 Answers

21

You could access single-value request parameters by ${param}.

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<input name="foo" value="${fn:escapeXml(param.foo)}">
<textarea name="bar">${fn:escapeXml(param.bar)}</textarea>
...
<input type="radio" name="faz" value="a" ${param.faz == 'a' ? 'checked' : ''} />
<input type="radio" name="faz" value="b" ${param.faz == 'b' ? 'checked' : ''} />
<input type="radio" name="faz" value="c" ${param.faz == 'c' ? 'checked' : ''} />
...
<select name="baz">
    <option value="a" ${param.baz == 'a' ? 'selected' : ''}>label a</option>
    <option value="b" ${param.baz == 'b' ? 'selected' : ''}>label b</option>
    <option value="c" ${param.baz == 'c' ? 'selected' : ''}>label c</option>
</select>

Do note that JSTL's fn:escapeXml() is necessary in order to prevent XSS attacks. See also XSS prevention in JSP/Servlet web application.

You could access multi-value request parameters by ${paramValues} and EL 3.0 streams.

<input type="checkbox" name="far" value="a" ${paramValues.far.stream().anyMatch(v->v == 'a').get() ? 'checked' : ''} />
<input type="checkbox" name="far" value="b" ${paramValues.far.stream().anyMatch(v->v == 'b').get() ? 'checked' : ''} />
<input type="checkbox" name="far" value="c" ${paramValues.far.stream().anyMatch(v->v == 'c').get() ? 'checked' : ''} />
...
<select name="boo" multiple>
    <option value="a" ${paramValues.boo.stream().anyMatch(v->v == 'a').get() ? 'selected' : ''}>label a</option>
    <option value="b" ${paramValues.boo.stream().anyMatch(v->v == 'b').get() ? 'selected' : ''}>label b</option>
    <option value="c" ${paramValues.boo.stream().anyMatch(v->v == 'c').get() ? 'selected' : ''}>label c</option>
</select>
Tuesday, June 1, 2021
 
iceduck
answered 7 Months ago
37
  • You can load the properties using java.util.Properties (or commons-configuration) in a ServletContextListener's contextInitialized(..) method.

  • register the listener with <listener> in web.xml

  • You then store the Properties into the ServletContext (you can get it from the event) (ctx.setAttribute("properties", properties)

  • then access the properties using ${applicationScope.properties.propName} (as BalusC noted, applicationScope is optional)

Update:

Initially I thought spring had some ready-to-use facility for that, but it turns out it's not exactly the case. You have two options:

  • this article explains something similar to my suggestion above, but using spring's PropertyPlaceholderConfigurer

  • this answer and this answer allow you to expose all your beans, including a PropertyPlaceholderConfigurer to the servlet context.

Wednesday, August 11, 2021
 
Jeffrey Stilwell
answered 4 Months ago
46

Sessions are unnecessary. Your basic plan should be:

  • Get variables from $_POST()
  • Validate form values.
  • Create an array with the values that passed validation.
  • Use the array to fill the values when redirected to the form.

Before I started using CodeIgniter, I used to use if statements to validate and generate error messages like this:

if ( ! empty($_POST['email'])){
    if ($this->verifyInput($_POST['email'], 6)){
        $fill['email'] = $_POST['email'];//$fill is the array of values that passed validation
    } else $tally++;//$tally keeps a running count of the total number of erors
}

I make a function call to $this->verifyInput which accepts the field value and the type of validation to perform--in this case it's 6, which indicates email. Here's my validation function:

function verifyInput($input, $type){
    if ($type == 0)     $pattern =  '/^1$/';//just the number 1
    elseif ($type == 1) $pattern =  '/^[0-9]+$/';//just integers
    elseif ($type == 2) $pattern =  '/^[A-Za-zÁ-Úá-úàÀÜü]+$/';//just letters
    elseif ($type == 3) $pattern =  '/^[0-9A-Za-zÁ-Úá-úàÀÜü]+$/';//integers & letters
    elseif ($type == 4) $pattern =  '/^[A-Za-zÁ-Úá-ú0-9àÀÜüs()/'":*,.;-!?&#$@]{1,1500}$/';//text
    elseif ($type == 5) $pattern =  '/^[A-Za-zÁ-Úá-úàÀÜü0-9']+[A-Za-zÁ-Úá-úàÀÜü0-9 '-.]+$/';//name
    elseif ($type == 6) $pattern = '/^.+@[^.].*.[a-z]{2,}$/';//e-mail
    elseif ($type == 7) $pattern = '/^(((0?[1-9][0-9]))|(0?[1-9][0-9]))?[ -.]?([1-9][0-9]{3})[ -.]?([0-9]{4})$/';//brazilian phone
    if (preg_match($pattern, $input) == 1) return true;
    else return false;
}

Once the validation is done, I use the $fill array to prefill the form for each field:

<input class="field" type="text" name="email" value = "<?php echo $fill['email']; ?>"/>

You should also make sure that $fill is iniciated with empty values such as $fill['email']=''; or check to make sure the values are set before filling the input tags:

<input class="field" type="text" name="email" value = "<?php if(isset($fill['email'])) echo $fill['email']; ?>"/>

These are just general guidelines that you can adapt to your needs, but I found this to be a convenient way to handle it.

Tuesday, August 17, 2021
 
OneNoOne
answered 4 Months ago
48

Take a look at form_tag.

<% form_tag '/posts' do %>
  <div><%= submit_tag 'Save' %></div>
<% end %>
Saturday, September 11, 2021
 
MonsterMMORPG
answered 3 Months ago
40

If you look at the top of generated jsp class, you will see the following line

 private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

Now, one possible solution to customize out object is to have a custom JspFactory implmentation.

Steps

Create a custom JspFactory implementation

public class MyJspFactory extends JspFactory {
    private static JspFactory _myFactory = null;
    public MyJspFactory(JspFactory factory) {
        _myFactory = factory;
    } 
   //All abstract methods which looks up _myFactory and does the same thing

   public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoflush) {
        PageContext myCtxt = _myFactory.getPageContext(....)
        //Create a customPageContext and wrap myCtxt in it and return
   }
}

Create a CutsomPageContext class

public class MyPageContext extends PageContext {
    private PageContext _ctxt = null;

    public void setPageContext(PageContext ctxt) {
        _ctxt = ctxt;
    }

    //Implement all abstract methods using _ctxt object

    @override
    public  JspWriter getOut() {
        JspWriter _out = _ctxt.getOut();

        //Wrap _out object using MyJSPWriter as mentioned in question and return back;

    }
}

Now during the init face of the servlets, add the following lines

JspFactory newFactory = new MyJspFactory(JspFactory.getDefaultFactory());
JspFactory.setDefaultFactory(newFactory);   

I have not tried it out. But conceptually it should work. Please let us know if you could achieve what you wanted through this.

Good Luck!

Thursday, September 23, 2021
 
Torxed
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share