<logic:messagesPresent> tag in Struts1 not looping through multiple errors in Action Messages - validation

I have a field in a bean that is failing 2 validations, as such 2 messages are being inserted in ActionMessages with the following command:
validationErrors.add("field1", new ActionMessage("Phone number is greater than 10 digits", false));
validationErrors.add("field1", new ActionMessage("Phone number has invalid characters", false));
Although I see the errors in the ActionMessages object (by setting a breakpoint in the debugger), only the first one gets displayed in my JSP, where I have:
<logic:messagesPresent message="true">
<html:messages id="message" property="field1" message="true">
<logic:present name="message">
<c:out value="${message}"/>
</logic:present>
</html:messages>
</logic:messagesPresent>
Why is only the first message displayed, when <html:messages> should loop through all the messages where the property is "field1"?

I ended up figuring out my issue and it had to do with how I am creating the new ActionMessage.
When you use:
public ActionMessage(<error message>, false)
While it allows you to display a literal value by using the <html:messages> tag in conjunction with either a <bean:write> or <c:out>, it won't iterate over multiple messages for a given property, why I don't know.
I tested and found that if I use a resource bundle and create the ActionMessage with a standard:
public ActionMessage(<key in resource bundle>)
I am able to display multiple messages for a single property.
Unfortunately, because I am using hibernate validator I don't want to use a resource bundle and struts to replace the values (would rather have the hibernate validator annotation replace values) and will likely just display a single message at a time for now.

Struts <logic:messagesPresent> tag checks that the messages exist on the current request.
Messages are found in the request under the key Globals.MESSAGE_KEY. If you use attribute message only messages are checked.
By default the tag will retrieve the request scope bean it will
iterate over from the Globals.ERROR_KEY constant string, but if this
attribute is set to true the request scope bean will be retrieved
from the Globals.MESSAGE_KEY constant string. Also if this is set to
true, any value assigned to the name attribute will be ignored.
The <html:messages> tag is used to display the messages if specified attribute message is true.
Now you have used a property attribute that filters messages for the given property.
Name of the property for which messages should be displayed. If not
specified, all messages (regardless of property) are displayed.
If you have only one message with the field1 property, then only one message will be displayed.
Look here how can you use action messages object
ActionMessages messages = new ActionMessages();
messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.common.field1.required");
saveMessages(request, messages); // storing messages as request attributes
Properties file:
error.common.field1.required = Field1 is required.
And display messages
<logic:messagesPresent message="true">
<html:messages id="message" message="true">
<bean:write name="message"/><br/>
</html:messages>
</logic:messagesPresent>
It will loop all massages under the global message key. If you want to use custom key you can use it with the parameter of ActionMessage
messages.add("field1", new ActionMessage("error.common.field1.required");
to retrieve the message
<logic:messagesPresent message="true">
<html:messages id="message" property="field1" message="true">
<bean:write name="message"/><br/>
</html:messages>
</logic:messagesPresent>

Related

how to invoke or get the sub-property value from Properties Tab in cypress

How to invoke the sub-property value from the properties tab. I need to get the value of the error.JPG in from Properties Tab
I tried with these different codes changes
cy.get('div [data-text-as-pseudo-element="error.JPG"]').invoke('prop','dataset').should('contain','error.JPG')
cy.get('div [data-text-as-pseudo-element="error.JPG"]').invoke('prop','dataset').should('contain','DOMStringMap')
cy.get('[data-text-as-pseudo-element="error.JPG"]').invoke('prop', 'dataset').then(dataset,()=>{
cy.wrap(dataset).invoke('prop','textAsPseudoElement').should('contain','error.JPG')
})
I'm getting Assertion Error
Timed out retrying after 4000ms: object tested must be an array, a map, an object, a set, a string, or a weakset, but domstringmap given
From HTMLElement.dataset
The dataset read-only property of the HTMLElement interface provides read/write access to custom data attributes (data-*) on elements. It exposes a map of strings (DOMStringMap) with an entry for each data-* attribute.
Your Cypress test can just treat it as a conventional attribute
cy.get('my-selector')
.should('have.attr', 'data-text-as-pseudo-element', 'error.JPG')
The tests you propose above are already complete with just this
cy.get('div[data-text-as-pseudo-element="error.JPG"]')
because the browser guarantees the attribute will be added to dataset.
If you want to work further with dataset in Javascript just chain the properties, e.g
cy.get('div[data-text-as-pseudo-element="error.JPG"]')
.should($el => {
const attrValue = $el[0].dataset.textAsPseudoElement
expect(attrValue).to.eq('error.JPG')
})

How to access field value in a JSR message with spring boot 2?

I would like to customize my error message in the following way:
Assume following declaration of a class Person:
#Size(min=10, max=250, message="{size.name}")
private String name;
Within the declared error message in ValidationMessages.properties I would like to output the field value as well, i.e. I would like to do something like this:
size.name = The name '${validatedvalue}' is invalid, its size must be between {min} and {max}
Assume the content of the field 'name' is “xyz”. Then the error message should look like this:
The name 'xyz' is invalid, its size must be between 10 and 250
The substitution for min and max works, but filed value i am getting as '' ,how can I do this for the field value?

grape-api - Force empty string to set values to null

I am creating an API endpoint which contains a file upload field and a few string fields. My goal is to allow clients to clear values on those string fields, i.e. the DB should persist these values as null.
However, due to the fact that the request may contain files, the client should be setting the Content-type header to multipart/form-data. This implies that client cannot send a representation of "null", but can only send an empty string to indicate the intent of clearing the value for a given string field.
Is there a way for grape-api library to know that when it is receiving a multipart request it should be able to nullify blank string values in the params, or is there a better approach to what I am trying to achieve?
Grape.configure do |config|
config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder
end
you can override the param builder. extend the default one and override the build_params method or monkey patch it.
params.transform_values {|v| v.eql?('') ? nil : v }

How to serialize empty string to selfclosing tag

Using JMS Serializer
I need to get self closing tag setting empty string
<logout/>
I always get
<logout></logout>
I can't use
->setSerializeNull(true)
because the class I'm serializing has many properties that if they are null they can't be serialized
Any idea how to get it done ?

Apache Camel / xpath operation result detection

Given a Camel route that is supposed to extract some inner parts of an XML message, create a new message from it then pass it on.
from(SUB_EXTRACT_XML)
.setExchangePattern(ExchangePattern.InOut)
.setBody().xpath("//mmsg:MyMessage/mmsg:AnyPayload/*", namespaces)
.setBody().simple("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n${in.body}")
.to(...)
For correct input messages like this (an "embedded" xml message is inside defined in schema by xs:any), it's working since the message is what I expect it to be:
<mmsg:MyMessage>
<mmsg:RandomTags/>
...
<mmsg:AnyPayload> <!-- xs:any in xsd -->
<some><xml/><here/></some>
</mmsg:AnyPayload>
</mmsg:MyMessage>
Given there is some issues with the XML message, such as the mmsg:AnyPayload tag is missing, so that the XPATH can't do its job:
<mmsg:MyMessage>
<mmsg:RandomTags/>
...
<some><xml/><here/></some>
</mmsg:MyMessage>
The XPATH will fail to extract the data and the entire XML message (including mmsg:MyMessage) is passed on, which is not intended. I rather throw some exception at this stage.
Question:
Is there a way to check if the xpath expression actually found the element refered to later in the route or if it failed to extract the given element(s)?
I know I could have done some schema validation of the message before and reject rubbish messages, but are there any way to see if a XPath expression fails?
A solution would be to use the choice() DSL in the route like this:
from(SUB_EXTRACT_XML)
.setExchangePattern(ExchangePattern.InOut)
.choice()
.when(xpath("//mmsg:MyMessage/mmsg:AnyPayload", namespaces))
.setHeader("Status", "OK") // just for another example how to transmit some variable between two routes
.setBody().simple("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n${in.body}")
.endChoice()
.otherwise()
.log(LoggingLevel.ERROR, "LoggerName", "Error message; Stop the processing")
.stop()
.endChoice()
.end()
// Just to show the headers are following the route...
.to("DIRECT_GO_FORWARD");
from("DIRECT_GO_FORWARD")
.setExchangePattern(ExchangePattern.InOut)
.choice()
.when(header("Status").isEqualTo("OK"))
.bean(new SampleProcessor())
...
.end()
...
.to("...");
the second route is just there to show you can use the header set in the first route (and the body too).

Resources