I have an ApplicationAdvice class that passes a reference to a profile picture on every page:
#ControllerAdvice
public class ApplicationAdvice {
...
#ModelAttribute("currentProfilePicture")
public String currentProfilePicture(Principal principal, Model model) {
if (principal != null) {
String currentProfilePicture = "#{/images/default-profile-picture.png}";
log.info(currentProfilePicture);
model.addAttribute("currentProfilePicture", currentProfilePicture);
return currentProfilePicture;
} else {
String currentProfilePicture = "#{/images/default-profile-picture.png}";
log.info(currentProfilePicture);
model.addAttribute("currentProfilePicture", currentProfilePicture);
return currentProfilePicture;
}
}
}
HTML:
<img class="profilePicture hvr-pulse-grow" th:src="${currentProfilePicture}" />
Am I not escaping the static reference properly? #{/images/default-profile-picture.png} The url string prints out fine... I basically just want to pass a string to a static file to the img tag.
It should look like this:
String currentProfilePicture = "/images/default-profile-picture.png";
<img class="profilePicture hvr-pulse-grow" th:src="#{${currentProfilePicture}}" />
You can't pass an entire thymeleaf string to be evaluated without doing some tricks with the preprocessing, but the above should do what you want.
Related
A problem occurs when I try to make POST request by an html page using thymeleaf. A controller should receive an input as an enum, but it throws an error:
java.lang.NoSuchMethodException: com.trade_analysis.model.StockSymbol.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3427) ~[na:na]"
I don't know what's not ok. I have seen some examples and have tried many things but I can't make it work as it should.
HTML:
<select class="form-item" th:field="${symbol}" required>
<option value="" selected disabled hidden id="default-symbol">Symbol</option>
<option class="dropdown-menu-button" th:each="symbolOption: ${symbols}" th:value="${symbolOption}" th:text="${symbolOption}"></option>
</select>
Java controler:
#GetMapping(value = "/stocks")
#PreAuthorize(value = "isAuthenticated()")
public String getStockPrices(Model model) throws UserNotFoundException {
User user = userService.getUserByUsername(getUsername());
String apiKey = user.getApiKey() == null ? "" : user.getApiKey();
model.addAttribute("apiKey", apiKey);
model.addAttribute("symbol", "");
model.addAttribute("symbols", asList(StockSymbol.values()));
return "stock-prices-preview";
}
#PostMapping(value = "/stocks")
#PreAuthorize(value = "isAuthenticated()")
public String stockPrices(#ModelAttribute String apiKey, #ModelAttribute StockSymbol symbol, Model model) {
model.addAttribute("apiKey", apiKey);
model.addAttribute("symbol", symbol);
model.addAttribute("symbols", asList(StockSymbol.values()));
return "stock-prices-preview";
}
'StockSymbol' enum:
public enum StockSymbol {
GOOGL("GOOGL"),
MSFT("MSFT"),
AMZN("AMZN"),
IBM("IBM"),
CSCO("CSCO"),
AAPL("AAPL");
String sys;
StockSymbol(String sys) {
this.sys = sys;
}
}
First few lines of error (full error is on: https://pastebin.com/kg8RR7G6)
java.lang.NoSuchMethodException: com.trade_analysis.model.StockSymbol.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3427) ~[na:na]
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2631) ~[na:na]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:216) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
In your POST handler you have this line:
public String stockPrices(#ModelAttribute String apiKey, #ModelAttribute StockSymbol symbol, Model model) {
Remove the #ModelAttribute annotation. Your problem is that Spring tries to instantiate the enum when it runs the controller method.
Use #RequestParam to obtain the incoming POST parameter by name. You might need to specify the parameter name in the annotation if your compiler doesn't use the -parameters switch.
I am developing one sample web application using JSP and Servlets, in this application i have set some object in the Servlets, i can retrieve that value in JSP by using request.getAttribute("Object"). Here i want to iterate that array of value in JSP. How can i achieve this any one help me.
My servlet code:
ArrayList<Performer> Performerobj=new ArrayList<Performer>();
ResultSet rst = stm1.executeQuery("some query");
while (rst.next())
{
Performer obj=new Performer();
obj.setProject(projectname);
obj.setCount(rst.getString("COUNT"));
obj.setDate(rst.getString("DATE"));
obj.setEmpid(rst.getString("empid"));
Performerobj.add(obj);
}
request.setAttribute("Performer", Performerobj);
Performer.java
public class Performer {
private String project;
private String empid;
private String date;
private String count;
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
/*setter and getter...... for all*/
Perform.jsp
<% List<Performer>obj1=List<Performer>)request.getAttribute("Performerobj"); %>
<script>
var obj=<%=obj1%>
for(obj object : list)
{
/*IS it correct way or how can i iterate*/
}
</script>
You can do that if you transform the ArrayList object into a JSON using a library like Jackson:
<% List<Performer>obj1 = (List<Performer>) request.getAttribute("Performerobj"); %>
<script>
var obj=<%=new ObjectMapper().writeValueAsString(obj1)%>;
for(obj object : list)
{
/*IS it correct way or how can i iterate*/
}
</script>
Another option is to use JSTL:
<c:forEach var="performer" items="${Performerobj}">
<c:out value="${performer.project}"/>
</c:forEach>
I use spring-social-facebook to interact with Graph API (1.0.3.RELEASE if it's metter). And I can't find any operation to retrieve profile's image url. I found only operations which return array of bytes and they are not very convenient for the implementation.
Does any kind of operation which retrieves image url exist in Spring Social?
If not, is there any 'tidy' workaround for this?
Thanks!
Finally, I didn't find any mention of profile picture url in spring social
My solution:
Initially I planned to extend UserOperations (FacebokTemplate.userOperations) class and add new method. But it's a package-level class and doens't visible outside.
So I decided to create my own template class extending FacebookTemplate and implement the method in this way:
public String fetchPictureUrl(String userId, ImageType imageType) {
URI uri = URIBuilder.fromUri(GRAPH_API_URL + userId + "/picture" +
"?type=" + imageType.toString().toLowerCase() + "&redirect=false").build();
JsonNode response = getRestTemplate().getForObject(uri, JsonNode.class);
return response.get("data").get("url").getTextValue();
}
i just ran into same issue, hope this will help someone else
Connection<Facebook> connection = userConnectionRepository.findPrimaryConnection(Facebook.class);
connection.createData().getImageUrl()
You could take the miniature picture in this way :
"http://graph.facebook.com/" + fbUser.getId() + "/picture?type=square"
In social API you have ability just to fetch the image binary file:
byte[] profileImage = facebook.userOperations().getUserProfileImage(imageType);
To get URL you need to have something custom (as mentioned in the post above).
I took the part of code from Facebook Social API (see Facebook template source code for fetchImage) and the following utility class:
public final class FacebookUtils {
private static final String PICTURE_PATH = "picture";
private static final String TYPE_PARAMETER = "type";
private static final String WIDTH_PARAMETER = "width";
private static final String HEIGHT_PARAMETER = "height";
private FacebookUtils() {
}
public static String getUserProfileImageUrl(Facebook facebook, String userId, String width, String height, ImageType imageType) {
URIBuilder uriBuilder = URIBuilder.fromUri(facebook.getBaseGraphApiUrl() + userId + StringUtils.SLASH_CHARACTER + PICTURE_PATH);
if (imageType != null) {
uriBuilder.queryParam(TYPE_PARAMETER, imageType.toString().toLowerCase());
}
if (width != null) {
uriBuilder.queryParam(WIDTH_PARAMETER, width.toString());
}
if (height != null) {
uriBuilder.queryParam(HEIGHT_PARAMETER, height.toString());
}
URI uri = uriBuilder.build();
return uri.toString();
}
}
I want to pass textfield with id value pat to the getautocomplete.action in Struts 2. Here I am using TINY.box to pop up the next page.
<s:textfield name="pat" id="pat"/>
<script type="text/javascript">
T$('tiny_patient').onkeypress = function(){
TINY.box.show('getautocomplete.action',1,0,0,1)
}
</script>
You need to append the id pat and its value to the url that you pass to the show function. For example
var url = 'getautocomplete.action?pat=' + $("#pat").val();
You can then use the variable url in your show function.
You also need to add the following in your action class. This also depends on the java type of pat. I am using String,
private String pat;
public String getPat()
{
return pat;
}
public void setPat(final String value)
{
this.pat = value;
}
Note
It is recommended to get your url using the following instead of hard-coding the extension
<s:url id="url_variable" namespace="/namespace_of_action" action="action_name" />
var url = '<s:property value="url_variable" />?pat=' + $("#pat").val();
If you are trying to populate the box based on previous box selection or any server side process you have to use ajax.
In your action class , write a getter-setter for variable named "pat" like this:
private string pat;
public getPat()
{
.........
}
public setPat(String pat)
{
this.pat=pat;
}
and change
TINY.box.show('getautocomplete.action',1,0,0,1)
to
TINY.box.show('getautocomplete.action?pat="xyz"',1,0,0,1)
Hope this will solve your problem unless you have an idea about ajax.
Try
<s:textfield name="pat" id="pat"/>
<script type="text/javascript">
document.getElementById("tiny_patient").onkeypress = function(e){
TINY.box.show("<s:url action='getautocomplete'/>"+"?pat="+document.getElementById("pat").value,1,0,0,1)
}
</script>
I am using TomCat 5.5 with MyFaces 1.1 and am trying to implement a custom regex validation tag.
My RegExValidator class looks like this:
public class RegExValidator implements Validator, StateHolder {
private String regex;
private boolean transientValue = false;
public RegExValidator() {
super();
}
public RegExValidator(String regex) {
this();
this.regex = regex;
}
public void validate(FacesContext context, UIComponent component, Object toValidate) throws ValidatorException {
if ((context == null) || (component == null)) {
throw new NullPointerException();
}
if (!(component instanceof UIInput)) {
return;
}
if (null == regex || null == toValidate) {
return;
}
String val = (String) toValidate;
if (!val.matches(regex)) {
FacesMessage errMsg = MessageFactory.createFacesMessage(context, Constants.FORMAT_INVALID_MESSAGE_ID, FacesMessage.SEVERITY_ERROR, (new Object[]{regex}));
throw new ValidatorException(errMsg);
}
}
public Object saveState(FacesContext context) {
Object[] values = new Object[1];
values[0] = regex;
return (values);
}
public void restoreState(FacesContext context, Object state) {
Object[] values = (Object[]) state;
regex = (String) values[0];
}
public String getRegex() {
return regex;
}
public void setRegex(String regex) {
this.regex = regex;
}
public boolean isTransient() {
return transientValue;
}
public void setTransient(boolean transientValue) {
this.transientValue = transientValue;
}
}
My RegExValidatorTag class looks like this:
#SuppressWarnings("serial")
public class RegExValidatorTag extends ValidatorELTag {
private static String validatorID = null;
protected ValueExpression regex = null;
public RegExValidatorTag() {
super();
if (validatorID == null) {
validatorID = "RegExValidator";
}
}
public Validator createValidator() throws JspException {
FacesContext facesContext = FacesContext.getCurrentInstance();
RegExValidator result = null;
if (validatorID != null) {
result = (RegExValidator) facesContext.getApplication().createValidator(validatorID);
}
String patterns = null;
if (regex != null) {
if (!regex.isLiteralText()) {
patterns = (String) regex.getValue(facesContext.getELContext());
} else {
patterns = regex.getExpressionString();
}
}
result.setRegex(patterns);
return result;
}
public void setValidatorID(String validatorID) {
RegExValidatorTag.validatorID = validatorID;
}
/**
* #param regex
* the regex to set
*/
public void setRegex(ValueExpression regex) {
this.regex = regex;
}
}
My Taglibrary Descriptor looks like this:
<tag>
<name>regexValidator</name>
<tag-class>com.company.components.taglib.RegExValidatorTag</tag-class>
<attribute>
<name>regex</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
My face-common-config.xml has a Validator tag like this:
<validator>
<description>
Validate an input string value against a regular
expression specified by the "regex" attribute.
</description>
<validator-id>RegExValidator</validator-id>
<validator-class>com.company.components.validators.RegExValidator</validator-class>
<attribute>
<description>
The regular expression to test the value against
</description>
<attribute-name>regex</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
</validator>
And later on it is supposed to be used in a jsp file like this:
<tc:in value="${dataBean.currentBean.field}">
<a:regexValidator regex="${dataBean.currentBean.validationRegEx}" />
</tc:in>
When calling the page, the following error comes up:
javax.servlet.ServletException: javax.servlet.jsp.JspException: org.apache.jasper.JasperException: Unable to convert string "[\d{4}]" to class "javax.el.ValueExpression" for attribute "regex": Property Editor not registered with the PropertyEditorManager
Caused by:
org.apache.jasper.JasperException - Unable to convert string "[\d{4}]" to class "javax.el.ValueExpression" for attribute "regex": Property Editor not registered with the PropertyEditorManager
I hope I provided enough details for someone to help me out on this...
I seem to have a similar problem like yours, I'm trying to find the solution but seems that the problem is when using Tomcat or the application server(WebSphere Application Server 7.0) JSF libraries, my problem is that the new application server has new JSF libraries (1.2) instead of the 1.1 libraries that my old application server had. (Version 6.1)
To be more specific. my problem is described here. http://www-01.ibm.com/support/docview.wss?uid=swg21318801